From 179f3810767492e6760a9abb0764f48db631bd5e Mon Sep 17 00:00:00 2001 From: Henning Rogge Date: Thu, 11 Dec 2008 22:04:19 +0100 Subject: [PATCH] --- yaml --- r: 122790 b: refs/heads/master c: 420e7fabd9c6d907280ed6b3e40eef425c5d8d8d h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/net/cxgb3/adapter.h | 1 - trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h | 7 --- trunk/drivers/net/cxgb3/cxgb3_offload.c | 67 +++++++----------------- trunk/drivers/net/cxgb3/sge.c | 67 ++---------------------- trunk/drivers/net/ppp_generic.c | 6 ++- trunk/drivers/net/usb/asix.c | 5 +- trunk/drivers/net/usb/catc.c | 41 +++++++-------- trunk/drivers/net/usb/dm9601.c | 5 +- trunk/drivers/net/usb/kaweth.c | 17 +++--- trunk/drivers/net/usb/mcs7830.c | 5 +- trunk/drivers/net/usb/pegasus.c | 33 ++++++------ trunk/drivers/net/usb/rtl8150.c | 38 ++++++-------- trunk/drivers/net/usb/smsc95xx.c | 5 +- trunk/include/linux/nl80211.h | 31 +++++++++++ trunk/include/net/cfg80211.h | 40 ++++++++++++++ trunk/net/mac80211/cfg.c | 25 ++++++++- trunk/net/wireless/nl80211.c | 58 +++++++++++++++++++- 18 files changed, 244 insertions(+), 209 deletions(-) diff --git a/[refs] b/[refs] index 2b7309ec9156..8e554517b6cf 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c94cb314503a69492bf4455dce4f6d300cff0851 +refs/heads/master: 420e7fabd9c6d907280ed6b3e40eef425c5d8d8d diff --git a/trunk/drivers/net/cxgb3/adapter.h b/trunk/drivers/net/cxgb3/adapter.h index 5b346f9eaa8b..c190a69c4d71 100644 --- a/trunk/drivers/net/cxgb3/adapter.h +++ b/trunk/drivers/net/cxgb3/adapter.h @@ -63,7 +63,6 @@ struct port_info { struct link_config link_config; struct net_device_stats netstats; int activity; - __be32 iscsi_ipv4addr; }; enum { /* adapter flags */ diff --git a/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h b/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h index 55099eb3c70e..1d8d46eb3c96 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h +++ b/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h @@ -57,7 +57,6 @@ enum { RDMA_GET_MIB = 19, GET_RX_PAGE_INFO = 50, - GET_ISCSI_IPV4ADDR = 51, }; /* @@ -87,12 +86,6 @@ struct iff_mac { u16 vlan_tag; }; -/* Structure used to request a port's iSCSI IPv4 address */ -struct iscsi_ipv4addr { - struct net_device *dev; /* the net_device */ - __be32 ipv4addr; /* the return iSCSI IPv4 address */ -}; - struct pci_dev; /* diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.c b/trunk/drivers/net/cxgb3/cxgb3_offload.c index 1ce69b742804..265aa8a15afa 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.c +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.c @@ -182,9 +182,7 @@ static struct net_device *get_iff_from_mac(struct adapter *adapter, static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req, void *data) { - int i; int ret = 0; - unsigned int val = 0; struct ulp_iscsi_info *uiip = data; switch (req) { @@ -193,55 +191,32 @@ static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req, uiip->llimit = t3_read_reg(adapter, A_ULPRX_ISCSI_LLIMIT); uiip->ulimit = t3_read_reg(adapter, A_ULPRX_ISCSI_ULIMIT); uiip->tagmask = t3_read_reg(adapter, A_ULPRX_ISCSI_TAGMASK); - - val = t3_read_reg(adapter, A_ULPRX_ISCSI_PSZ); - for (i = 0; i < 4; i++, val >>= 8) - uiip->pgsz_factor[i] = val & 0xFF; - - val = t3_read_reg(adapter, A_TP_PARA_REG7); - uiip->max_txsz = - uiip->max_rxsz = min((val >> S_PMMAXXFERLEN0)&M_PMMAXXFERLEN0, - (val >> S_PMMAXXFERLEN1)&M_PMMAXXFERLEN1); /* * On tx, the iscsi pdu has to be <= tx page size and has to * fit into the Tx PM FIFO. */ - val = min(adapter->params.tp.tx_pg_size, - t3_read_reg(adapter, A_PM1_TX_CFG) >> 17); - uiip->max_txsz = min(val, uiip->max_txsz); - - /* set MaxRxData to 16224 */ - val = t3_read_reg(adapter, A_TP_PARA_REG2); - if ((val >> S_MAXRXDATA) != 0x3f60) { - val &= (M_RXCOALESCESIZE << S_RXCOALESCESIZE); - val |= V_MAXRXDATA(0x3f60); - printk(KERN_INFO - "%s, iscsi set MaxRxData to 16224 (0x%x).\n", - adapter->name, val); - t3_write_reg(adapter, A_TP_PARA_REG2, val); - } - - /* - * on rx, the iscsi pdu has to be < rx page size and the - * the max rx data length programmed in TP - */ - val = min(adapter->params.tp.rx_pg_size, - ((t3_read_reg(adapter, A_TP_PARA_REG2)) >> - S_MAXRXDATA) & M_MAXRXDATA); - uiip->max_rxsz = min(val, uiip->max_rxsz); + uiip->max_txsz = min(adapter->params.tp.tx_pg_size, + t3_read_reg(adapter, A_PM1_TX_CFG) >> 17); + /* on rx, the iscsi pdu has to be < rx page size and the + whole pdu + cpl headers has to fit into one sge buffer */ + uiip->max_rxsz = min_t(unsigned int, + adapter->params.tp.rx_pg_size, + (adapter->sge.qs[0].fl[1].buf_size - + sizeof(struct cpl_rx_data) * 2 - + sizeof(struct cpl_rx_data_ddp))); break; case ULP_ISCSI_SET_PARAMS: t3_write_reg(adapter, A_ULPRX_ISCSI_TAGMASK, uiip->tagmask); + /* set MaxRxData and MaxCoalesceSize to 16224 */ + t3_write_reg(adapter, A_TP_PARA_REG2, 0x3f603f60); /* program the ddp page sizes */ - for (i = 0; i < 4; i++) - val |= (uiip->pgsz_factor[i] & 0xF) << (8 * i); - if (val && (val != t3_read_reg(adapter, A_ULPRX_ISCSI_PSZ))) { - printk(KERN_INFO - "%s, setting iscsi pgsz 0x%x, %u,%u,%u,%u.\n", - adapter->name, val, uiip->pgsz_factor[0], - uiip->pgsz_factor[1], uiip->pgsz_factor[2], - uiip->pgsz_factor[3]); - t3_write_reg(adapter, A_ULPRX_ISCSI_PSZ, val); + { + int i; + unsigned int val = 0; + for (i = 0; i < 4; i++) + val |= (uiip->pgsz_factor[i] & 0xF) << (8 * i); + if (val) + t3_write_reg(adapter, A_ULPRX_ISCSI_PSZ, val); } break; default: @@ -432,12 +407,6 @@ static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data) rx_page_info->page_size = tp->rx_pg_size; rx_page_info->num = tp->rx_num_pgs; break; - case GET_ISCSI_IPV4ADDR: { - struct iscsi_ipv4addr *p = data; - struct port_info *pi = netdev_priv(p->dev); - p->ipv4addr = pi->iscsi_ipv4addr; - break; - } default: return -EOPNOTSUPP; } diff --git a/trunk/drivers/net/cxgb3/sge.c b/trunk/drivers/net/cxgb3/sge.c index 6c641a889471..63eb97473c8b 100644 --- a/trunk/drivers/net/cxgb3/sge.c +++ b/trunk/drivers/net/cxgb3/sge.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "common.h" #include "regs.h" #include "sge_defs.h" @@ -1863,54 +1862,6 @@ static void restart_tx(struct sge_qset *qs) } } -/** - * cxgb3_arp_process - process an ARP request probing a private IP address - * @adapter: the adapter - * @skb: the skbuff containing the ARP request - * - * Check if the ARP request is probing the private IP address - * dedicated to iSCSI, generate an ARP reply if so. - */ -static void cxgb3_arp_process(struct adapter *adapter, struct sk_buff *skb) -{ - struct net_device *dev = skb->dev; - struct port_info *pi; - struct arphdr *arp; - unsigned char *arp_ptr; - unsigned char *sha; - __be32 sip, tip; - - if (!dev) - return; - - skb_reset_network_header(skb); - arp = arp_hdr(skb); - - if (arp->ar_op != htons(ARPOP_REQUEST)) - return; - - arp_ptr = (unsigned char *)(arp + 1); - sha = arp_ptr; - arp_ptr += dev->addr_len; - memcpy(&sip, arp_ptr, sizeof(sip)); - arp_ptr += sizeof(sip); - arp_ptr += dev->addr_len; - memcpy(&tip, arp_ptr, sizeof(tip)); - - pi = netdev_priv(dev); - if (tip != pi->iscsi_ipv4addr) - return; - - arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha, - dev->dev_addr, sha); - -} - -static inline int is_arp(struct sk_buff *skb) -{ - return skb->protocol == htons(ETH_P_ARP); -} - /** * rx_eth - process an ingress ethernet packet * @adap: the adapter @@ -1934,7 +1885,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, pi = netdev_priv(skb->dev); if (pi->rx_csum_offload && p->csum_valid && p->csum == htons(0xffff) && !p->fragment) { - qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; + rspq_to_qset(rq)->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else skb->ip_summed = CHECKSUM_NONE; @@ -1949,28 +1900,16 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, grp, ntohs(p->vlan), p); - else { - if (unlikely(pi->iscsi_ipv4addr && - is_arp(skb))) { - unsigned short vtag = ntohs(p->vlan) & - VLAN_VID_MASK; - skb->dev = vlan_group_get_device(grp, - vtag); - cxgb3_arp_process(adap, skb); - } + else __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan), rq->polling); - } else dev_kfree_skb_any(skb); } else if (rq->polling) { if (lro) lro_receive_skb(&qs->lro_mgr, skb, p); - else { - if (unlikely(pi->iscsi_ipv4addr && is_arp(skb))) - cxgb3_arp_process(adap, skb); + else netif_receive_skb(skb); - } } else netif_rx(skb); } diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index c832d600d1e8..3ee7830d458d 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -179,7 +179,7 @@ struct channel { */ static DEFINE_MUTEX(all_ppp_mutex); static atomic_t ppp_unit_count = ATOMIC_INIT(0); -static DEFINE_IDR(ppp_units_idr); +static struct idr ppp_units_idr; /* * all_channels_lock protects all_channels and last_channel_index, @@ -852,6 +852,8 @@ static int __init ppp_init(void) "ppp"); } + idr_init(&ppp_units_idr); + out: if (err) printk(KERN_ERR "failed to register PPP device (%d)\n", err); @@ -2433,7 +2435,7 @@ ppp_create_interface(int unit, int *retp) if (unit_find(&ppp_units_idr, unit)) goto out2; /* unit already exists */ else { - /* darn, someone is cheating us? */ + /* darn, someone is cheatting us? */ *retp = -EINVAL; goto out2; } diff --git a/trunk/drivers/net/usb/asix.c b/trunk/drivers/net/usb/asix.c index e009481c606c..de57490103fc 100644 --- a/trunk/drivers/net/usb/asix.c +++ b/trunk/drivers/net/usb/asix.c @@ -246,11 +246,10 @@ static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, static void asix_async_cmd_callback(struct urb *urb) { struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; - int status = urb->status; - if (status < 0) + if (urb->status < 0) printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d", - status); + urb->status); kfree(req); usb_free_urb(urb); diff --git a/trunk/drivers/net/usb/catc.c b/trunk/drivers/net/usb/catc.c index cb7acbbb2798..d7621239059a 100644 --- a/trunk/drivers/net/usb/catc.c +++ b/trunk/drivers/net/usb/catc.c @@ -229,15 +229,14 @@ static void catc_rx_done(struct urb *urb) u8 *pkt_start = urb->transfer_buffer; struct sk_buff *skb; int pkt_len, pkt_offset = 0; - int status = urb->status; if (!catc->is_f5u011) { clear_bit(RX_RUNNING, &catc->flags); pkt_offset = 2; } - if (status) { - dbg("rx_done, status %d, length %d", status, urb->actual_length); + if (urb->status) { + dbg("rx_done, status %d, length %d", urb->status, urb->actual_length); return; } @@ -274,12 +273,12 @@ static void catc_rx_done(struct urb *urb) if (catc->is_f5u011) { if (atomic_read(&catc->recq_sz)) { - int state; + int status; atomic_dec(&catc->recq_sz); dbg("getting extra packet"); urb->dev = catc->usbdev; - if ((state = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { - dbg("submit(rx_urb) status %d", state); + if ((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { + dbg("submit(rx_urb) status %d", status); } } else { clear_bit(RX_RUNNING, &catc->flags); @@ -291,9 +290,8 @@ static void catc_irq_done(struct urb *urb) { struct catc *catc = urb->context; u8 *data = urb->transfer_buffer; - int status = urb->status; + int status; unsigned int hasdata = 0, linksts = LinkNoChange; - int res; if (!catc->is_f5u011) { hasdata = data[1] & 0x80; @@ -309,7 +307,7 @@ static void catc_irq_done(struct urb *urb) linksts = LinkBad; } - switch (status) { + switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ @@ -318,7 +316,7 @@ static void catc_irq_done(struct urb *urb) return; /* -EPIPE: should clear the halt */ default: /* error */ - dbg("irq_done, status %d, data %02x %02x.", status, data[0], data[1]); + dbg("irq_done, status %d, data %02x %02x.", urb->status, data[0], data[1]); goto resubmit; } @@ -338,17 +336,17 @@ static void catc_irq_done(struct urb *urb) atomic_inc(&catc->recq_sz); } else { catc->rx_urb->dev = catc->usbdev; - if ((res = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) { - err("submit(rx_urb) status %d", res); + if ((status = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) { + err("submit(rx_urb) status %d", status); } } } resubmit: - res = usb_submit_urb (urb, GFP_ATOMIC); - if (res) + status = usb_submit_urb (urb, GFP_ATOMIC); + if (status) err ("can't resubmit intr, %s-%s, status %d", catc->usbdev->bus->bus_name, - catc->usbdev->devpath, res); + catc->usbdev->devpath, status); } /* @@ -380,9 +378,9 @@ static void catc_tx_done(struct urb *urb) { struct catc *catc = urb->context; unsigned long flags; - int r, status = urb->status; + int r; - if (status == -ECONNRESET) { + if (urb->status == -ECONNRESET) { dbg("Tx Reset."); urb->status = 0; catc->netdev->trans_start = jiffies; @@ -392,8 +390,8 @@ static void catc_tx_done(struct urb *urb) return; } - if (status) { - dbg("tx_done, status %d, length %d", status, urb->actual_length); + if (urb->status) { + dbg("tx_done, status %d, length %d", urb->status, urb->actual_length); return; } @@ -504,10 +502,9 @@ static void catc_ctrl_done(struct urb *urb) struct catc *catc = urb->context; struct ctrl_queue *q; unsigned long flags; - int status = urb->status; - if (status) - dbg("ctrl_done, status %d, len %d.", status, urb->actual_length); + if (urb->status) + dbg("ctrl_done, status %d, len %d.", urb->status, urb->actual_length); spin_lock_irqsave(&catc->ctrl_lock, flags); diff --git a/trunk/drivers/net/usb/dm9601.c b/trunk/drivers/net/usb/dm9601.c index edd244f3acb5..db3377dae9d5 100644 --- a/trunk/drivers/net/usb/dm9601.c +++ b/trunk/drivers/net/usb/dm9601.c @@ -123,11 +123,10 @@ static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value) static void dm_write_async_callback(struct urb *urb) { struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; - int status = urb->status; - if (status < 0) + if (urb->status < 0) printk(KERN_DEBUG "dm_write_async_callback() failed with %d\n", - status); + urb->status); kfree(req); usb_free_urb(urb); diff --git a/trunk/drivers/net/usb/kaweth.c b/trunk/drivers/net/usb/kaweth.c index 2ee034f70d1c..fdbf3be24fda 100644 --- a/trunk/drivers/net/usb/kaweth.c +++ b/trunk/drivers/net/usb/kaweth.c @@ -516,9 +516,8 @@ static void int_callback(struct urb *u) { struct kaweth_device *kaweth = u->context; int act_state; - int status = u->status; - switch (status) { + switch (u->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ @@ -599,7 +598,6 @@ static void kaweth_usb_receive(struct urb *urb) { struct kaweth_device *kaweth = urb->context; struct net_device *net = kaweth->net; - int status = urb->status; int count = urb->actual_length; int count2 = urb->transfer_buffer_length; @@ -608,7 +606,7 @@ static void kaweth_usb_receive(struct urb *urb) struct sk_buff *skb; - if(unlikely(status == -ECONNRESET || status == -ESHUTDOWN)) + if(unlikely(urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) /* we are killed - set a flag and wake the disconnect handler */ { kaweth->end = 1; @@ -623,10 +621,10 @@ static void kaweth_usb_receive(struct urb *urb) } spin_unlock(&kaweth->device_lock); - if(status && status != -EREMOTEIO && count != 1) { + if(urb->status && urb->status != -EREMOTEIO && count != 1) { err("%s RX status: %d count: %d packet_len: %d", net->name, - status, + urb->status, count, (int)pkt_len); kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); @@ -777,11 +775,10 @@ static void kaweth_usb_transmit_complete(struct urb *urb) { struct kaweth_device *kaweth = urb->context; struct sk_buff *skb = kaweth->tx_skb; - int status = urb->status; - if (unlikely(status != 0)) - if (status != -ENOENT) - dbg("%s: TX status %d.", kaweth->net->name, status); + if (unlikely(urb->status != 0)) + if (urb->status != -ENOENT) + dbg("%s: TX status %d.", kaweth->net->name, urb->status); netif_wake_queue(kaweth->net); dev_kfree_skb_irq(skb); diff --git a/trunk/drivers/net/usb/mcs7830.c b/trunk/drivers/net/usb/mcs7830.c index 5385d66b306e..bbcc76ae3c9c 100644 --- a/trunk/drivers/net/usb/mcs7830.c +++ b/trunk/drivers/net/usb/mcs7830.c @@ -115,11 +115,10 @@ static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data) static void mcs7830_async_cmd_callback(struct urb *urb) { struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; - int status = urb->status; - if (status < 0) + if (urb->status < 0) printk(KERN_DEBUG "%s() failed with %d\n", - __func__, status); + __func__, urb->status); kfree(req); usb_free_urb(urb); diff --git a/trunk/drivers/net/usb/pegasus.c b/trunk/drivers/net/usb/pegasus.c index 166880c113d6..075e8e94225e 100644 --- a/trunk/drivers/net/usb/pegasus.c +++ b/trunk/drivers/net/usb/pegasus.c @@ -99,12 +99,11 @@ static int update_eth_regs_async(pegasus_t *); static void ctrl_callback(struct urb *urb) { pegasus_t *pegasus = urb->context; - int status = urb->status; if (!pegasus) return; - switch (status) { + switch (urb->status) { case 0: if (pegasus->flags & ETH_REGS_CHANGE) { pegasus->flags &= ~ETH_REGS_CHANGE; @@ -120,7 +119,7 @@ static void ctrl_callback(struct urb *urb) default: if (netif_msg_drv(pegasus) && printk_ratelimit()) dev_dbg(&pegasus->intf->dev, "%s, status %d\n", - __func__, status); + __func__, urb->status); } pegasus->flags &= ~ETH_REGS_CHANGED; wake_up(&pegasus->ctrl_wait); @@ -612,7 +611,6 @@ static void read_bulk_callback(struct urb *urb) pegasus_t *pegasus = urb->context; struct net_device *net; int rx_status, count = urb->actual_length; - int status = urb->status; u8 *buf = urb->transfer_buffer; __u16 pkt_len; @@ -623,7 +621,7 @@ static void read_bulk_callback(struct urb *urb) if (!netif_device_present(net) || !netif_running(net)) return; - switch (status) { + switch (urb->status) { case 0: break; case -ETIME: @@ -641,11 +639,11 @@ static void read_bulk_callback(struct urb *urb) case -ECONNRESET: case -ESHUTDOWN: if (netif_msg_ifdown(pegasus)) - pr_debug("%s: rx unlink, %d\n", net->name, status); + pr_debug("%s: rx unlink, %d\n", net->name, urb->status); return; default: if (netif_msg_rx_err(pegasus)) - pr_debug("%s: RX status %d\n", net->name, status); + pr_debug("%s: RX status %d\n", net->name, urb->status); goto goon; } @@ -771,7 +769,6 @@ static void write_bulk_callback(struct urb *urb) { pegasus_t *pegasus = urb->context; struct net_device *net; - int status = urb->status; if (!pegasus) return; @@ -781,7 +778,7 @@ static void write_bulk_callback(struct urb *urb) if (!netif_device_present(net) || !netif_running(net)) return; - switch (status) { + switch (urb->status) { case -EPIPE: /* FIXME schedule_work() to clear the tx halt */ netif_stop_queue(net); @@ -793,11 +790,11 @@ static void write_bulk_callback(struct urb *urb) case -ECONNRESET: case -ESHUTDOWN: if (netif_msg_ifdown(pegasus)) - pr_debug("%s: tx unlink, %d\n", net->name, status); + pr_debug("%s: tx unlink, %d\n", net->name, urb->status); return; default: if (netif_msg_tx_err(pegasus)) - pr_info("%s: TX status %d\n", net->name, status); + pr_info("%s: TX status %d\n", net->name, urb->status); /* FALL THROUGH */ case 0: break; @@ -811,13 +808,13 @@ static void intr_callback(struct urb *urb) { pegasus_t *pegasus = urb->context; struct net_device *net; - int res, status = urb->status; + int status; if (!pegasus) return; net = pegasus->net; - switch (status) { + switch (urb->status) { case 0: break; case -ECONNRESET: /* unlink */ @@ -830,7 +827,7 @@ static void intr_callback(struct urb *urb) */ if (netif_msg_timer(pegasus)) pr_debug("%s: intr status %d\n", net->name, - status); + urb->status); } if (urb->actual_length >= 6) { @@ -857,12 +854,12 @@ static void intr_callback(struct urb *urb) pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4]; } - res = usb_submit_urb(urb, GFP_ATOMIC); - if (res == -ENODEV) + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status == -ENODEV) netif_device_detach(pegasus->net); - if (res && netif_msg_timer(pegasus)) + if (status && netif_msg_timer(pegasus)) printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n", - net->name, res); + net->name, status); } static void pegasus_tx_timeout(struct net_device *net) diff --git a/trunk/drivers/net/usb/rtl8150.c b/trunk/drivers/net/usb/rtl8150.c index d8664bf18c00..6133401ebc67 100644 --- a/trunk/drivers/net/usb/rtl8150.c +++ b/trunk/drivers/net/usb/rtl8150.c @@ -212,9 +212,8 @@ static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) static void ctrl_callback(struct urb *urb) { rtl8150_t *dev; - int status = urb->status; - switch (status) { + switch (urb->status) { case 0: break; case -EINPROGRESS: @@ -222,7 +221,7 @@ static void ctrl_callback(struct urb *urb) case -ENOENT: break; default: - dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status); + dev_warn(&urb->dev->dev, "ctrl urb status %d\n", urb->status); } dev = urb->context; clear_bit(RX_REG_SET, &dev->flags); @@ -425,8 +424,7 @@ static void read_bulk_callback(struct urb *urb) struct sk_buff *skb; struct net_device *netdev; u16 rx_stat; - int status = urb->status; - int result; + int status; dev = urb->context; if (!dev) @@ -437,7 +435,7 @@ static void read_bulk_callback(struct urb *urb) if (!netif_device_present(netdev)) return; - switch (status) { + switch (urb->status) { case 0: break; case -ENOENT: @@ -446,7 +444,7 @@ static void read_bulk_callback(struct urb *urb) dev_warn(&urb->dev->dev, "may be reset is needed?..\n"); goto goon; default: - dev_warn(&urb->dev->dev, "Rx status %d\n", status); + dev_warn(&urb->dev->dev, "Rx status %d\n", urb->status); goto goon; } @@ -476,10 +474,10 @@ static void read_bulk_callback(struct urb *urb) goon: usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); - result = usb_submit_urb(dev->rx_urb, GFP_ATOMIC); - if (result == -ENODEV) + status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC); + if (status == -ENODEV) netif_device_detach(dev->netdev); - else if (result) { + else if (status) { set_bit(RX_URB_FAIL, &dev->flags); goto resched; } else { @@ -532,7 +530,6 @@ static void rx_fixup(unsigned long data) static void write_bulk_callback(struct urb *urb) { rtl8150_t *dev; - int status = urb->status; dev = urb->context; if (!dev) @@ -540,9 +537,9 @@ static void write_bulk_callback(struct urb *urb) dev_kfree_skb_irq(dev->tx_skb); if (!netif_device_present(dev->netdev)) return; - if (status) + if (urb->status) dev_info(&urb->dev->dev, "%s: Tx status %d\n", - dev->netdev->name, status); + dev->netdev->name, urb->status); dev->netdev->trans_start = jiffies; netif_wake_queue(dev->netdev); } @@ -551,13 +548,12 @@ static void intr_callback(struct urb *urb) { rtl8150_t *dev; __u8 *d; - int status = urb->status; - int res; + int status; dev = urb->context; if (!dev) return; - switch (status) { + switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ @@ -567,7 +563,7 @@ static void intr_callback(struct urb *urb) /* -EPIPE: should clear the halt */ default: dev_info(&urb->dev->dev, "%s: intr status %d\n", - dev->netdev->name, status); + dev->netdev->name, urb->status); goto resubmit; } @@ -595,13 +591,13 @@ static void intr_callback(struct urb *urb) } resubmit: - res = usb_submit_urb (urb, GFP_ATOMIC); - if (res == -ENODEV) + status = usb_submit_urb (urb, GFP_ATOMIC); + if (status == -ENODEV) netif_device_detach(dev->netdev); - else if (res) + else if (status) err ("can't resubmit intr, %s-%s/input0, status %d", dev->udev->bus->bus_name, - dev->udev->devpath, res); + dev->udev->devpath, status); } static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message) diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index 5574abe29c73..fed22ffedd57 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -311,10 +311,9 @@ static void smsc95xx_async_cmd_callback(struct urb *urb, struct pt_regs *regs) { struct usb_context *usb_context = urb->context; struct usbnet *dev = usb_context->dev; - int status = urb->status; - if (status < 0) - devwarn(dev, "async callback failed with %d", status); + if (urb->status < 0) + devwarn(dev, "async callback failed with %d", urb->status); complete(&usb_context->notify); diff --git a/trunk/include/linux/nl80211.h b/trunk/include/linux/nl80211.h index 04d4516f9c71..7501acfcfdc4 100644 --- a/trunk/include/linux/nl80211.h +++ b/trunk/include/linux/nl80211.h @@ -424,6 +424,32 @@ enum nl80211_sta_flags { NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 }; +/** + * enum nl80211_rate_info - bitrate information + * + * These attribute types are used with %NL80211_STA_INFO_TXRATE + * when getting information about the bitrate of a station. + * + * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved + * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) + * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) + * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate + * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval + * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined + * @__NL80211_RATE_INFO_AFTER_LAST: internal use + */ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, + NL80211_RATE_INFO_BITRATE, + NL80211_RATE_INFO_MCS, + NL80211_RATE_INFO_40_MHZ_WIDTH, + NL80211_RATE_INFO_SHORT_GI, + + /* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, + NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1 +}; + /** * enum nl80211_sta_info - station information * @@ -436,6 +462,9 @@ enum nl80211_sta_flags { * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute + * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) + * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute + * containing info as possible, see &enum nl80211_sta_info_txrate. */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID, @@ -445,6 +474,8 @@ enum nl80211_sta_info { NL80211_STA_INFO_LLID, NL80211_STA_INFO_PLID, NL80211_STA_INFO_PLINK_STATE, + NL80211_STA_INFO_SIGNAL, + NL80211_STA_INFO_TX_BITRATE, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index a0c0bf19496c..65e03ac93109 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -169,6 +169,9 @@ struct station_parameters { * @STATION_INFO_LLID: @llid filled * @STATION_INFO_PLID: @plid filled * @STATION_INFO_PLINK_STATE: @plink_state filled + * @STATION_INFO_SIGNAL: @signal filled + * @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled + * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -177,6 +180,39 @@ enum station_info_flags { STATION_INFO_LLID = 1<<3, STATION_INFO_PLID = 1<<4, STATION_INFO_PLINK_STATE = 1<<5, + STATION_INFO_SIGNAL = 1<<6, + STATION_INFO_TX_BITRATE = 1<<7, +}; + +/** + * enum station_info_rate_flags - bitrate info flags + * + * Used by the driver to indicate the specific rate transmission + * type for 802.11n transmissions. + * + * @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled + * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission + * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval + */ +enum rate_info_flags { + RATE_INFO_FLAGS_MCS = 1<<0, + RATE_INFO_FLAGS_40_MHZ_WIDTH = 1<<1, + RATE_INFO_FLAGS_SHORT_GI = 1<<2, +}; + +/** + * struct rate_info - bitrate information + * + * Information about a receiving or transmitting bitrate + * + * @flags: bitflag of flags from &enum rate_info_flags + * @mcs: mcs index if struct describes a 802.11n bitrate + * @legacy: bitrate in 100kbit/s for 802.11abg + */ +struct rate_info { + u8 flags; + u8 mcs; + u16 legacy; }; /** @@ -191,6 +227,8 @@ enum station_info_flags { * @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state + * @signal: signal strength of last received packet in dBm + * @txrate: current unicast bitrate to this station */ struct station_info { u32 filled; @@ -200,6 +238,8 @@ struct station_info { u16 llid; u16 plid; u8 plink_state; + s8 signal; + struct rate_info txrate; }; /** diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 7912eb14eca0..23b5eeaf7bc5 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->filled = STATION_INFO_INACTIVE_TIME | STATION_INFO_RX_BYTES | - STATION_INFO_TX_BYTES; + STATION_INFO_TX_BYTES | + STATION_INFO_TX_BITRATE; sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; + if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { + sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = (s8)sta->last_signal; + } + + sinfo->txrate.flags = 0; + if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) + sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; + if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI) + sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + + if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) { + struct ieee80211_supported_band *sband; + sband = sta->local->hw.wiphy->bands[ + sta->local->hw.conf.channel->band]; + sinfo->txrate.legacy = + sband->bitrates[sta->last_tx_rate.idx].bitrate; + } else + sinfo->txrate.mcs = sta->last_tx_rate.idx; + if (ieee80211_vif_is_mesh(&sdata->vif)) { #ifdef CONFIG_MAC80211_MESH sinfo->filled |= STATION_INFO_LLID | diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 4335f76be71f..93c9b983ce08 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -1091,12 +1091,46 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags) return 0; } +static u16 nl80211_calculate_bitrate(struct rate_info *rate) +{ + int modulation, streams, bitrate; + + if (!(rate->flags & RATE_INFO_FLAGS_MCS)) + return rate->legacy; + + /* the formula below does only work for MCS values smaller than 32 */ + if (rate->mcs >= 32) + return 0; + + modulation = rate->mcs & 7; + streams = (rate->mcs >> 3) + 1; + + bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ? + 13500000 : 6500000; + + if (modulation < 4) + bitrate *= (modulation + 1); + else if (modulation == 4) + bitrate *= (modulation + 2); + else + bitrate *= (modulation + 3); + + bitrate *= streams; + + if (rate->flags & RATE_INFO_FLAGS_SHORT_GI) + bitrate = (bitrate / 9) * 10; + + /* do NOT round down here */ + return (bitrate + 50000) / 100000; +} + static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, int flags, struct net_device *dev, u8 *mac_addr, struct station_info *sinfo) { void *hdr; - struct nlattr *sinfoattr; + struct nlattr *sinfoattr, *txrate; + u16 bitrate; hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr) @@ -1126,7 +1160,29 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (sinfo->filled & STATION_INFO_PLINK_STATE) NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE, sinfo->plink_state); + if (sinfo->filled & STATION_INFO_SIGNAL) + NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL, + sinfo->signal); + if (sinfo->filled & STATION_INFO_TX_BITRATE) { + txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE); + if (!txrate) + goto nla_put_failure; + + /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */ + bitrate = nl80211_calculate_bitrate(&sinfo->txrate); + if (bitrate > 0) + NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate); + if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS) + NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS, + sinfo->txrate.mcs); + if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) + NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH); + if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI) + NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI); + + nla_nest_end(msg, txrate); + } nla_nest_end(msg, sinfoattr); return genlmsg_end(msg, hdr);