* Re: : Emit event stream compat iw_point objects correctly.
From: David Miller @ 2008-01-10 9:16 UTC (permalink / raw)
To: mokuno; +Cc: linux-wireless, netdev
In-Reply-To: <20071227181439.6F59.40F06B3A@sm.sony.co.jp>
From: Masakazu Mokuno <mokuno@sm.sony.co.jp>
Date: Thu, 27 Dec 2007 18:24:40 +0900
> On ppc64 (PS3), IW_EV_LCP_LEN is 8, not 4.
>
> include/linux/wireless.h:
>
> #define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
>
> where sizeof(struct iw_event) == 24, sizeof(union iwreq_data) == 16 on
> PS3.
Here is a new version of the last patch (#12), it should handle
all of these cases properly now.
Let me know if you spot any more errors.
Thanks!
[WEXT]: Emit event stream entries correctly when compat.
Three major portions to this change:
1) Add IW_EV_COMPAT_LCP_LEN, IW_EV_COMPAT_POINT_OFF,
and IW_EV_COMPAT_POINT_LEN helper defines.
2) Delete iw_stream_check_add_*(), they are unused.
3) Add iw_request_info argument to iwe_stream_add_*(), and use it to
size the event and pointer lengths correctly depending upon whether
IW_REQUEST_FLAG_COMPAT is set or not.
4) The mechanical transformations to the drivers and wireless stack
bits to get the iw_request_info passed down into the routines
modified in #3.
With help from Masakazu Mokuno
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/wireless/airo.c | 39 +++++---
drivers/net/wireless/atmel.c | 24 ++++-
drivers/net/wireless/hostap/hostap.h | 3 +-
drivers/net/wireless/hostap/hostap_ap.c | 32 +++---
drivers/net/wireless/hostap/hostap_ioctl.c | 54 ++++++-----
drivers/net/wireless/libertas/scan.c | 35 ++++---
drivers/net/wireless/orinoco.c | 30 ++++--
drivers/net/wireless/prism54/isl_ioctl.c | 45 +++++----
drivers/net/wireless/wl3501_cs.c | 10 +-
drivers/net/wireless/zd1201.c | 21 +++--
include/linux/wireless.h | 16 +++
include/net/iw_handler.h | 150 ++++++++--------------------
net/ieee80211/ieee80211_wx.c | 44 +++++----
net/mac80211/ieee80211_i.h | 5 +-
net/mac80211/ieee80211_ioctl.c | 2 +-
net/mac80211/ieee80211_sta.c | 59 ++++++-----
16 files changed, 293 insertions(+), 276 deletions(-)
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 074055e..ad4f140 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -7234,6 +7234,7 @@ out:
* format that the Wireless Tools will understand - Jean II
*/
static inline char *airo_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
char *current_ev,
char *end_buf,
BSSListRid *bss)
@@ -7249,7 +7250,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -7259,7 +7261,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -7269,7 +7272,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
/* Add frequency */
@@ -7280,7 +7284,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
*/
iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
@@ -7298,7 +7303,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
| IW_QUAL_DBM;
}
iwe.u.qual.noise = ai->wstats.qual.noise;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -7307,7 +7313,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
/* Rate : stuffing multiple values in a single event require a bit
* more of magic - Jean II */
@@ -7324,7 +7331,9 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
if((current_val - current_ev) > IW_EV_LCP_LEN)
@@ -7336,7 +7345,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", bss->beaconInterval);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
kfree(buf);
}
@@ -7370,8 +7380,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, (char *) info_element);
+ current_ev = iwe_stream_add_point(
+ info, current_ev,
+ end_buf, &iwe,
+ (char *) info_element);
}
break;
@@ -7379,8 +7391,9 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, (char *) info_element);
+ current_ev = iwe_stream_add_point(
+ info, current_ev, end_buf,
+ &iwe, (char *) info_element);
break;
default:
@@ -7419,7 +7432,7 @@ static int airo_get_scan(struct net_device *dev,
list_for_each_entry (net, &ai->network_list, list) {
/* Translate to WE format this entry */
- current_ev = airo_translate_scan(dev, current_ev,
+ current_ev = airo_translate_scan(dev, info, current_ev,
extra + dwrq->length,
&net->bss);
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 059ce3f..985068e 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2320,30 +2320,40 @@ static int atmel_get_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_ADDR_LEN);
iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
if (iwe.u.data.length > 32)
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, priv->BSSinfo[i].SSID);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = priv->BSSinfo[i].BSStype;
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = priv->BSSinfo[i].channel;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
iwe.u.qual.level = priv->BSSinfo[i].RSSI;
iwe.u.qual.qual = iwe.u.qual.level;
/* iwe.u.qual.noise = SOMETHING */
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_QUAL_LEN);
iwe.cmd = SIOCGIWENCODE;
@@ -2352,7 +2362,9 @@ static int atmel_get_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, NULL);
}
/* Length of data */
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 547ba84..3a386a6 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -67,7 +67,8 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size,
int aplist);
-int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
+int prism2_ap_translate_scan(struct net_device *dev,
+ struct iw_request_info *info, char *buffer);
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 6bbdb76..8131e84 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -2381,7 +2381,8 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
/* Translate our list of Access Points & Stations to a card independant
* format that the Wireless Tools will understand - Jean II */
-int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
+int prism2_ap_translate_scan(struct net_device *dev,
+ struct iw_request_info *info, char *buffer)
{
struct hostap_interface *iface;
local_info_t *local;
@@ -2410,8 +2411,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
iwe.len = IW_EV_ADDR_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Use the mode to indicate if it's a station or
* an Access Point */
@@ -2422,8 +2423,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
else
iwe.u.mode = IW_MODE_INFRA;
iwe.len = IW_EV_UINT_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
/* Some quality */
memset(&iwe, 0, sizeof(iwe));
@@ -2438,8 +2439,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
iwe.u.qual.updated = sta->last_rx_updated;
iwe.len = IW_EV_QUAL_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
if (sta->ap) {
@@ -2447,8 +2448,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = sta->u.ap.ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe,
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe,
sta->u.ap.ssid);
memset(&iwe, 0, sizeof(iwe));
@@ -2458,10 +2459,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe,
- sta->u.ap.ssid
- /* 0 byte memcpy */);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe,
+ sta->u.ap.ssid);
if (sta->u.ap.channel > 0 &&
sta->u.ap.channel <= FREQ_COUNT) {
@@ -2471,7 +2471,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
* 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(
- current_ev, end_buf, &iwe,
+ info, current_ev, end_buf, &iwe,
IW_EV_FREQ_LEN);
}
@@ -2480,8 +2480,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
sprintf(buf, "beacon_interval=%d",
sta->listen_interval);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index d8f5efc..5b04054 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1794,6 +1794,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev,
#ifndef PRISM2_NO_STATION_MODES
static char * __prism2_translate_scan(local_info_t *local,
+ struct iw_request_info *info,
struct hfa384x_hostscan_result *scan,
struct hostap_bss_info *bss,
char *current_ev, char *end_buf)
@@ -1824,7 +1825,7 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -1833,7 +1834,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, ssid);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWMODE;
@@ -1848,8 +1850,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1865,8 +1867,8 @@ static char * __prism2_translate_scan(local_info_t *local,
if (chan > 0) {
iwe.u.freq.m = freq_list[chan - 1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
}
if (scan) {
@@ -1885,8 +1887,8 @@ static char * __prism2_translate_scan(local_info_t *local,
| IW_QUAL_NOISE_UPDATED
| IW_QUAL_QUAL_INVALID
| IW_QUAL_DBM;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1896,7 +1898,7 @@ static char * __prism2_translate_scan(local_info_t *local,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
/* TODO: add SuppRates into BSS table */
if (scan) {
@@ -1910,7 +1912,7 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
current_val = iwe_stream_add_value(
- current_ev, current_val, end_buf, &iwe,
+ info, current_ev, current_val, end_buf, &iwe,
IW_EV_PARAM_LEN);
}
/* Check if we added any event */
@@ -1925,15 +1927,15 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
if (local->last_scan_type == PRISM2_HOSTSCAN &&
(capabilities & WLAN_CAPABILITY_IBSS)) {
@@ -1941,8 +1943,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
}
}
kfree(buf);
@@ -1951,16 +1953,16 @@ static char * __prism2_translate_scan(local_info_t *local,
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- current_ev = iwe_stream_add_point(
- current_ev, end_buf, &iwe, bss->wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->wpa_ie);
}
if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- current_ev = iwe_stream_add_point(
- current_ev, end_buf, &iwe, bss->rsn_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->rsn_ie);
}
return current_ev;
@@ -1970,6 +1972,7 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Translate scan data returned from the card to a card independant
* format that the Wireless Tools will understand - Jean II */
static inline int prism2_translate_scan(local_info_t *local,
+ struct iw_request_info *info,
char *buffer, int buflen)
{
struct hfa384x_hostscan_result *scan;
@@ -2000,13 +2003,14 @@ static inline int prism2_translate_scan(local_info_t *local,
if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
bss->included = 1;
current_ev = __prism2_translate_scan(
- local, scan, bss, current_ev, end_buf);
+ local, info, scan, bss, current_ev,
+ end_buf);
found++;
}
}
if (!found) {
current_ev = __prism2_translate_scan(
- local, scan, NULL, current_ev, end_buf);
+ local, info, scan, NULL, current_ev, end_buf);
}
/* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2024,7 +2028,7 @@ static inline int prism2_translate_scan(local_info_t *local,
bss = list_entry(ptr, struct hostap_bss_info, list);
if (bss->included)
continue;
- current_ev = __prism2_translate_scan(local, NULL, bss,
+ current_ev = __prism2_translate_scan(local, info, NULL, bss,
current_ev, end_buf);
/* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2071,7 +2075,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
}
local->scan_timestamp = 0;
- res = prism2_translate_scan(local, extra, data->length);
+ res = prism2_translate_scan(local, info, extra, data->length);
if (res >= 0) {
data->length = res;
@@ -2104,7 +2108,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev,
* Jean II */
/* Translate to WE format */
- res = prism2_ap_translate_scan(dev, extra);
+ res = prism2_ap_translate_scan(dev, info, extra);
if (res >= 0) {
printk(KERN_DEBUG "Scan result translation succeeded "
"(length=%d)\n", res);
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index ad1e67d..9dbd932 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -1444,8 +1444,9 @@ out:
#define MAX_CUSTOM_LEN 64
static inline char *libertas_translate_scan(wlan_private *priv,
- char *start, char *stop,
- struct bss_descriptor *bss)
+ struct iw_request_info *info,
+ char *start, char *stop,
+ struct bss_descriptor *bss)
{
wlan_adapter *adapter = priv->adapter;
struct chan_freq_power *cfp;
@@ -1470,24 +1471,24 @@ static inline char *libertas_translate_scan(wlan_private *priv,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
/* SSID */
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = min((u32) bss->ssid_len, (u32) IW_ESSID_MAX_SIZE);
- start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
+ start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
/* Mode */
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = bss->mode;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
/* Frequency */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = (long)cfp->freq * 100000;
iwe.u.freq.e = 1;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
@@ -1523,7 +1524,7 @@ static inline char *libertas_translate_scan(wlan_private *priv,
nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
iwe.u.qual.level = CAL_RSSI(snr, nf);
}
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -1533,7 +1534,7 @@ static inline char *libertas_translate_scan(wlan_private *priv,
iwe.u.data.flags = IW_ENCODE_DISABLED;
}
iwe.u.data.length = 0;
- start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
+ start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
current_val = start + IW_EV_LCP_LEN;
@@ -1545,8 +1546,8 @@ static inline char *libertas_translate_scan(wlan_private *priv,
for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) {
/* Bit rate given in 500 kb/s units */
iwe.u.bitrate.value = bss->rates[j] * 500000;
- current_val = iwe_stream_add_value(start, current_val,
- stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
if ((bss->mode == IW_MODE_ADHOC)
&& !libertas_ssid_cmp(adapter->curbssparams.ssid,
@@ -1554,8 +1555,8 @@ static inline char *libertas_translate_scan(wlan_private *priv,
bss->ssid, bss->ssid_len)
&& adapter->adhoccreate) {
iwe.u.bitrate.value = 22 * 500000;
- current_val = iwe_stream_add_value(start, current_val,
- stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
if((current_val - start) > IW_EV_LCP_LEN)
@@ -1567,7 +1568,7 @@ static inline char *libertas_translate_scan(wlan_private *priv,
memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1576,7 +1577,7 @@ static inline char *libertas_translate_scan(wlan_private *priv,
memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
if (bss->mesh) {
@@ -1588,7 +1589,8 @@ static inline char *libertas_translate_scan(wlan_private *priv,
"mesh-type: olpc");
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, custom);
}
out:
@@ -1650,7 +1652,8 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
}
/* Translate to WE format this entry */
- next_ev = libertas_translate_scan(priv, ev, stop, iter_bss);
+ next_ev = libertas_translate_scan(priv, info, ev, stop,
+ iter_bss);
if (next_ev == NULL)
continue;
ev = next_ev;
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index ca6c2da..9141b8f 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -3909,6 +3909,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
* format that the Wireless Tools will understand - Jean II
* Return message length or -errno for fatal errors */
static inline int orinoco_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
char *buffer,
char *scan,
int scan_len)
@@ -3979,7 +3980,8 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, atom->a.bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -3989,7 +3991,8 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, atom->a.essid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -3999,7 +4002,9 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe,
+ IW_EV_UINT_LEN);
}
channel = atom->s.channel;
@@ -4008,8 +4013,9 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = channel_frequency[channel-1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe,
+ IW_EV_FREQ_LEN);
}
/* Add quality statistics */
@@ -4023,7 +4029,8 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
else
iwe.u.qual.qual = 0;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -4032,7 +4039,8 @@ static inline int orinoco_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, atom->a.essid);
/* Bit rate is not available in Lucent/Agere firmwares */
if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
@@ -4055,9 +4063,9 @@ static inline int orinoco_translate_scan(struct net_device *dev,
break;
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((atom->p.rates[i] & 0x7f) * 500000);
- current_val = iwe_stream_add_value(current_ev, current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(
+ info, current_ev, current_val,
+ end_buf, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
if ((current_val - current_ev) > IW_EV_LCP_LEN)
@@ -4102,7 +4110,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
/* We have some results to push back to user space */
/* Translate to WE format */
- int ret = orinoco_translate_scan(dev, extra,
+ int ret = orinoco_translate_scan(dev, info, extra,
priv->scan_result,
priv->scan_len);
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 6d80ca4..4dc0b5e 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -572,8 +572,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
*/
static char *
-prism54_translate_bss(struct net_device *ndev, char *current_ev,
- char *end_buf, struct obj_bss *bss, char noise)
+prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
+ char *current_ev, char *end_buf, struct obj_bss *bss,
+ char noise)
{
struct iw_event iwe; /* Temporary buffer */
short cap;
@@ -585,8 +586,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
iwe.cmd = SIOCGIWAP;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* The following entries will be displayed in the same order we give them */
@@ -594,7 +595,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.length = bss->ssid.length;
iwe.u.data.flags = 1;
iwe.cmd = SIOCGIWESSID;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->ssid.octets);
/* Capabilities */
@@ -611,9 +612,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
/* Encryption capability */
if (cap & CAP_CRYPT)
@@ -622,14 +622,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
iwe.cmd = SIOCGIWENCODE;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, NULL);
/* Add frequency. (short) bss->channel is the frequency in MHz */
iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 6;
iwe.cmd = SIOCGIWFREQ;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.u.qual.level = bss->rssi;
@@ -637,16 +638,16 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
/* do a simple SNR for quality */
iwe.u.qual.qual = bss->rssi - noise;
iwe.cmd = IWEVQUAL;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add WPA/RSN Information Element, if any */
wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
if (wpa_ie_len > 0) {
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, wpa_ie);
}
/* Do the bitrates */
{
@@ -663,9 +664,9 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
for(i = 0; i < sizeof(scan_rate_list); i++) {
if(bss->rates & mask) {
iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
- current_val = iwe_stream_add_value(current_ev, current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(
+ info, current_ev, current_val,
+ end_buf, &iwe, IW_EV_PARAM_LEN);
}
mask <<= 1;
}
@@ -711,7 +712,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
/* ok now, scan the list and translate its info */
for (i = 0; i < (int) bsslist->nr; i++) {
- current_ev = prism54_translate_bss(ndev, current_ev,
+ current_ev = prism54_translate_bss(ndev, info, current_ev,
extra + dwrq->length,
&(bsslist->bsslist[i]),
noise);
@@ -2705,6 +2706,7 @@ prism2_ioctl_scan_req(struct net_device *ndev,
struct prism2_hostapd_param *param)
{
islpci_private *priv = netdev_priv(ndev);
+ struct iw_request_info info;
int i, rvalue;
struct obj_bsslist *bsslist;
u32 noise = 0;
@@ -2728,9 +2730,12 @@ prism2_ioctl_scan_req(struct net_device *ndev,
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
bsslist = r.ptr;
+ info.cmd = PRISM54_HOSTAPD;
+ info.flags = 0;
+
/* ok now, scan the list and translate its info */
for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
+ current_ev = prism54_translate_bss(ndev, current_ev, &info,
extra + IW_SCAN_MAX_DATA,
&(bsslist->bsslist[i]),
noise);
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 42a36b3..3771419 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1624,25 +1624,25 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = this->bss_set[i].ssid.el.len;
- current_ev = iwe_stream_add_point(current_ev,
+ current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe,
this->bss_set[i].ssid.essid);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = this->bss_set[i].bss_type;
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWENCODE;
@@ -1651,7 +1651,7 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev,
+ current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, NULL);
}
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index d5c0c66..10c8642 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1152,32 +1152,36 @@ static int zd1201_get_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = zd->rxdata[i+16];
iwe.u.data.flags = 1;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18);
+ cev = iwe_stream_add_point(info, cev, end_buf,
+ &iwe, zd->rxdata+i+18);
iwe.cmd = SIOCGIWMODE;
if (zd->rxdata[i+14]&0x01)
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = zd->rxdata[i+0];
iwe.u.freq.e = 0;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = 0;
iwe.u.bitrate.disabled = 0;
for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) {
iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000;
- cev=iwe_stream_add_event(cev, end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ cev=iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
iwe.cmd = SIOCGIWENCODE;
@@ -1186,14 +1190,15 @@ static int zd1201_get_scan(struct net_device *dev,
iwe.u.data.flags = IW_ENCODE_ENABLED;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
+ cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
iwe.cmd = IWEVQUAL;
iwe.u.qual.qual = zd->rxdata[i+4];
iwe.u.qual.noise= zd->rxdata[i+2]/10-100;
iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;
iwe.u.qual.updated = 7;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
}
if (!enabled_save)
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 2088524..bec73df 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1098,6 +1098,22 @@ struct iw_event
#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
IW_EV_POINT_OFF)
+#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+struct __compat_iw_event {
+ __u16 len; /* Real lenght of this stuff */
+ __u16 cmd; /* Wireless IOCTL */
+ compat_caddr_t pointer;
+};
+#define IW_EV_COMPAT_LCP_LEN \
+ (sizeof(struct __compat_iw_event) - sizeof(compat_caddr_t))
+#define IW_EV_COMPAT_POINT_OFF (((char *) \
+ &(((struct compat_iw_point *) NULL)->length)) - \
+ (char *) NULL)
+#define IW_EV_COMPAT_POINT_LEN \
+ (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
+ IW_EV_COMPAT_POINT_OFF)
+#endif
+
/* Size of the Event prefix when packed in stream */
#define IW_EV_LCP_PK_LEN (4)
/* Size of the various events when packed in stream */
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index c99a8ee..d6f0c51 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -483,19 +483,26 @@ extern void wireless_spy_update(struct net_device * dev,
* Wrapper to add an Wireless Event to a stream of events.
*/
static inline char *
-iwe_stream_add_event(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len) /* Real size of payload */
+iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends,
+ struct iw_event *iwe, int event_len)
{
+ int lcp_len = IW_EV_LCP_LEN;
+
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT) {
+ event_len -= IW_EV_LCP_LEN;
+ event_len += IW_EV_COMPAT_LCP_LEN;
+ lcp_len = IW_EV_COMPAT_LCP_LEN;
+ }
+#endif
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
/* Beware of alignement issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN,
- event_len - IW_EV_LCP_LEN);
+ memcpy(stream + lcp_len,
+ ((char *) iwe) + lcp_len,
+ event_len - lcp_len);
stream += event_len;
}
return stream;
@@ -507,104 +514,33 @@ iwe_stream_add_event(char * stream, /* Stream of events */
* stream of events.
*/
static inline char *
-iwe_stream_add_point(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload length + flags */
- char * extra) /* More payload */
+iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
+ struct iw_event *iwe, char *extra)
{
- int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
- /* Check if it's possible */
- if(likely((stream + event_len) < ends)) {
- iwe->len = event_len;
- memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
- IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
- stream += event_len;
+ int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
+ int point_len = IW_EV_POINT_LEN;
+ int lcp_len = IW_EV_LCP_LEN;
+ int point_off = IW_EV_POINT_OFF;
+
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT) {
+ event_len = IW_EV_COMPAT_POINT_LEN + iwe->u.data.length;
+ point_len = IW_EV_COMPAT_POINT_LEN;
+ lcp_len = IW_EV_COMPAT_LCP_LEN;
+ point_off = IW_EV_COMPAT_POINT_OFF;
}
- return stream;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper to add a value to a Wireless Event in a stream of events.
- * Be careful, this one is tricky to use properly :
- * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
- */
-static inline char *
-iwe_stream_add_value(char * event, /* Event in the stream */
- char * value, /* Value in event */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len) /* Real size of payload */
-{
- /* Don't duplicate LCP */
- event_len -= IW_EV_LCP_LEN;
+#endif
/* Check if it's possible */
- if(likely((value + event_len) < ends)) {
- /* Add new value */
- memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
- value += event_len;
- /* Patch LCP */
- iwe->len = value - event;
- memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
- }
- return value;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper to add an Wireless Event to a stream of events.
- * Same as above, with explicit error check...
- */
-static inline char *
-iwe_stream_check_add_event(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len, /* Size of payload */
- int * perr) /* Error report */
-{
- /* Check if it's possible, set error if not */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
- /* Beware of alignement issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN,
- event_len - IW_EV_LCP_LEN);
- stream += event_len;
- } else
- *perr = -E2BIG;
- return stream;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper to add an short Wireless Event containing a pointer to a
- * stream of events.
- * Same as above, with explicit error check...
- */
-static inline char *
-iwe_stream_check_add_point(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload length + flags */
- char * extra, /* More payload */
- int * perr) /* Error report */
-{
- int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
- /* Check if it's possible */
- if(likely((stream + event_len) < ends)) {
- iwe->len = event_len;
- memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
+ memcpy(stream + lcp_len,
+ ((char *) iwe) + lcp_len + point_off,
IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
+ memcpy(stream + point_len, extra, iwe->u.data.length);
stream += event_len;
- } else
- *perr = -E2BIG;
+ }
return stream;
}
@@ -613,29 +549,29 @@ iwe_stream_check_add_point(char * stream, /* Stream of events */
* Wrapper to add a value to a Wireless Event in a stream of events.
* Be careful, this one is tricky to use properly :
* At the first run, you need to have (value = event + IW_EV_LCP_LEN).
- * Same as above, with explicit error check...
*/
static inline char *
-iwe_stream_check_add_value(char * event, /* Event in the stream */
- char * value, /* Value in event */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len, /* Size of payload */
- int * perr) /* Error report */
+iwe_stream_add_value(struct iw_request_info *info, char *event, char *value,
+ char *ends, struct iw_event *iwe, int event_len)
{
+ int lcp_len = IW_EV_LCP_LEN;
+
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ lcp_len = IW_EV_COMPAT_LCP_LEN;
+#endif
/* Don't duplicate LCP */
event_len -= IW_EV_LCP_LEN;
/* Check if it's possible */
if(likely((value + event_len) < ends)) {
/* Add new value */
- memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
+ memcpy(value, (char *) iwe + lcp_len, event_len);
value += event_len;
/* Patch LCP */
iwe->len = value - event;
- memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
- } else
- *perr = -E2BIG;
+ memcpy(event, (char *) iwe, lcp_len);
+ }
return value;
}
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index d309e8f..cba556c 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -43,8 +43,9 @@ static const char *ieee80211_modes[] = {
#define MAX_CUSTOM_LEN 64
static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
- char *start, char *stop,
- struct ieee80211_network *network)
+ char *start, char *stop,
+ struct ieee80211_network *network,
+ struct iw_request_info *info)
{
char custom[MAX_CUSTOM_LEN];
char *p;
@@ -57,7 +58,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
/* Remaining entries will be displayed in the order we provide them */
@@ -66,17 +67,19 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.u.data.flags = 1;
if (network->flags & NETWORK_EMPTY_ESSID) {
iwe.u.data.length = sizeof("<hidden>");
- start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, "<hidden>");
} else {
iwe.u.data.length = min(network->ssid_len, (u8) 32);
- start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, network->ssid);
}
/* Add the protocol name */
iwe.cmd = SIOCGIWNAME;
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
ieee80211_modes[network->mode]);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -86,7 +89,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
else
iwe.u.mode = IW_MODE_ADHOC;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
+ start = iwe_stream_add_event(info, start, stop,
+ &iwe, IW_EV_UINT_LEN);
}
/* Add channel and frequency */
@@ -95,7 +99,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
iwe.u.freq.e = 6;
iwe.u.freq.i = 0;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -104,7 +108,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, network->ssid);
/* Add basic and extended rates */
/* Rate : stuffing multiple values in a single event require a bit
@@ -124,14 +129,16 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
for (; j < network->rates_ex_len; j++) {
rate = network->rates_ex[j] & 0x7F;
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any rate */
if((current_val - start) > IW_EV_LCP_LEN)
@@ -181,14 +188,14 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.u.qual.level = network->stats.signal;
}
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
iwe.cmd = IWEVCUSTOM;
p = custom;
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
memset(&iwe, 0, sizeof(iwe));
if (network->wpa_ie_len) {
@@ -196,7 +203,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
memcpy(buf, network->wpa_ie, network->wpa_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->wpa_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
memset(&iwe, 0, sizeof(iwe));
@@ -205,7 +212,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
memcpy(buf, network->rsn_ie, network->rsn_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->rsn_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
/* Add EXTRA: Age to display seconds since last beacon/probe response
@@ -217,7 +224,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
jiffies_to_msecs(jiffies - network->last_scanned));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
/* Add spectrum management information */
iwe.cmd = -1;
@@ -238,7 +245,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
if (iwe.cmd == IWEVCUSTOM) {
iwe.u.data.length = p - custom;
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
}
return start;
@@ -272,7 +279,8 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
if (ieee->scan_age == 0 ||
time_after(network->last_scanned + ieee->scan_age, jiffies))
- ev = ieee80211_translate_scan(ieee, ev, stop, network);
+ ev = ieee80211_translate_scan(ieee, ev, stop, network,
+ info);
else
IEEE80211_DEBUG_SCAN("Not showing network '%s ("
"%s)' due to age (%dms).\n",
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 72e1c93..b8306aa 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -23,6 +23,7 @@
#include <linux/spinlock.h>
#include <linux/etherdevice.h>
#include <net/wireless.h>
+#include <net/iw_handler.h>
#include "ieee80211_key.h"
#include "sta_info.h"
@@ -748,7 +749,9 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid);
int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len);
void ieee80211_sta_req_auth(struct net_device *dev,
struct ieee80211_if_sta *ifsta);
-int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len);
+int ieee80211_sta_scan_results(struct net_device *dev,
+ struct iw_request_info *info,
+ char *buf, size_t len);
void ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_rx_status *rx_status);
void ieee80211_rx_bss_list_init(struct net_device *dev);
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 7027eed..0f686f1 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -560,7 +560,7 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
if (local->sta_scanning)
return -EAGAIN;
- res = ieee80211_sta_scan_results(dev, extra, data->length);
+ res = ieee80211_sta_scan_results(dev, info, extra, data->length);
if (res >= 0) {
data->length = res;
return 0;
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index bee8080..b176e13 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -2881,6 +2881,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
static char *
ieee80211_sta_scan_result(struct net_device *dev,
+ struct iw_request_info *info,
struct ieee80211_sta_bss *bss,
char *current_ev, char *end_buf)
{
@@ -2907,15 +2908,15 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = bss->ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
memset(&iwe, 0, sizeof(iwe));
@@ -2924,20 +2925,20 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
iwe.u.freq.m = bss->freq * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVQUAL;
@@ -2945,8 +2946,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.u.qual.level = bss->rssi;
iwe.u.qual.noise = bss->noise;
iwe.u.qual.updated = local->wstats_flags;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWENCODE;
@@ -2955,22 +2956,22 @@ ieee80211_sta_scan_result(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
if (bss && bss->wpa_ie) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- bss->wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->wpa_ie);
}
if (bss && bss->rsn_ie) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- bss->rsn_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->rsn_ie);
}
if (bss && bss->supp_rates_len > 0) {
@@ -2986,8 +2987,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
for (i = 0; i < bss->supp_rates_len; i++) {
iwe.u.bitrate.value = ((bss->supp_rates[i] &
0x7f) * 500000);
- p = iwe_stream_add_value(current_ev, p,
- end_buf, &iwe, IW_EV_PARAM_LEN);
+ p = iwe_stream_add_value(info, current_ev, p, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
current_ev = p;
}
@@ -3000,8 +3001,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
kfree(buf);
}
}
@@ -3020,15 +3021,15 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", bss->beacon_int);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "capab=0x%04x", bss->capability);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
kfree(buf);
break;
@@ -3038,7 +3039,9 @@ ieee80211_sta_scan_result(struct net_device *dev,
}
-int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
+int ieee80211_sta_scan_results(struct net_device *dev,
+ struct iw_request_info *info,
+ char *buf, size_t len)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
char *current_ev = buf;
@@ -3051,8 +3054,8 @@ int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
spin_unlock_bh(&local->sta_bss_lock);
return -E2BIG;
}
- current_ev = ieee80211_sta_scan_result(dev, bss, current_ev,
- end_buf);
+ current_ev = ieee80211_sta_scan_result(dev, info, bss,
+ current_ev, end_buf);
}
spin_unlock_bh(&local->sta_bss_lock);
return current_ev - buf;
--
1.5.4.rc2.84.gf85fd
^ permalink raw reply related
* Re: [git patches] net driver fixes
From: Meelis Roos @ 2008-01-10 9:24 UTC (permalink / raw)
To: David Miller; +Cc: jeff, netdev, shemminger
In-Reply-To: <20080107.135621.259663114.davem@davemloft.net>
> > Well, it's 2.6.24-rc7 already - any news?
>
> I put this into my net-2.6 tree last night since Jeff asked
> me to look over critical networking driver stuff for a little
> while.
Thanks, they are upstream now and it did fix tulip in my PPC - network
is stable again.
--
Meelis Roos (mroos@linux.ee)
^ permalink raw reply
* [PATCH] drivers/net/niu: Support for Marvell PHY
From: Mirko Lindner @ 2008-01-10 9:33 UTC (permalink / raw)
To: netdev; +Cc: davem
This patch makes necessary changes in the Neptune driver to support
the new Marvell PHY. It also adds support for the LED blinking
on Neptune cards with Marvell PHY. All registers are using defines
in the niu.h header file as is already done for the BCM8704 registers.
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/net/niu.c linux-2.6-changed/drivers/net/niu.c
--- linux-2.6/drivers/net/niu.c 2007-12-10 14:14:04.000000000 +0100
+++ linux-2.6-changed/drivers/net/niu.c 2008-01-09 14:32:59.000000000 +0100
@@ -801,22 +801,86 @@ static int bcm8704_init_user_dev3(struct
return 0;
}
-static int xcvr_init_10g(struct niu *np)
+void mrvl88x2011_act_led(struct niu *np, int val)
+{
+ int err;
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_8_TO_11_CTL);
+ err &= ~MRVL88X2011_LED(MRVL88X2011_LED_ACT,MRVL88X2011_LED_CTL_MASK);
+ err |= MRVL88X2011_LED(MRVL88X2011_LED_ACT,val);
+
+ (void) mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_8_TO_11_CTL, err);
+}
+
+void mrvl88x2011_led_blink_rate(struct niu *np, int rate)
+{
+ int err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_BLINK_CTL);
+ if (err >= 0) {
+ err &= ~MRVL88X2011_LED_BLKRATE_MASK;
+ err |= (rate << 4);
+
+ (void) mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_BLINK_CTL, err);
+ }
+}
+
+static int xcvr_init_10g_mrvl88x2011(struct niu *np)
+{
+ int err;
+
+ /* Set LED functions */
+ mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS);
+ mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF); /* led activity */
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_GENERAL_CTL);
+ if (err < 0) {
+ return(err);
+ }
+
+ err |= MRVL88X2011_ENA_XFPREFCLK;
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_GENERAL_CTL, err);
+ if (err < 0) {
+ return(err);
+ }
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_CTL_1);
+ if (err < 0) {
+ return(err);
+ }
+
+ if (np->link_config.loopback_mode == LOOPBACK_MAC) {
+ err |= MRVL88X2011_LOOPBACK;
+ }
+ else {
+ err &= ~MRVL88X2011_LOOPBACK;
+ }
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_CTL_1, err);
+ if (err < 0) {
+ return(err);
+ }
+
+ /* Enable PMD */
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX);
+
+ return (err);
+}
+
+static int xcvr_init_10g_bcm8704(struct niu *np)
{
struct niu_link_config *lp = &np->link_config;
u16 analog_stat0, tx_alarm_status;
int err;
- u64 val;
-
- val = nr64_mac(XMAC_CONFIG);
- val &= ~XMAC_CONFIG_LED_POLARITY;
- val |= XMAC_CONFIG_FORCE_LED_ON;
- nw64_mac(XMAC_CONFIG, val);
-
- /* XXX shared resource, lock parent XXX */
- val = nr64(MIF_CONFIG);
- val |= MIF_CONFIG_INDIRECT_MODE;
- nw64(MIF_CONFIG, val);
err = bcm8704_reset(np);
if (err)
@@ -896,6 +960,39 @@ static int xcvr_init_10g(struct niu *np)
return 0;
}
+static int xcvr_init_10g(struct niu *np)
+{
+ int err;
+ u64 val;
+ int phy_id;
+
+ val = nr64_mac(XMAC_CONFIG);
+ val &= ~XMAC_CONFIG_LED_POLARITY;
+ val |= XMAC_CONFIG_FORCE_LED_ON;
+ nw64_mac(XMAC_CONFIG, val);
+
+ /* XXX shared resource, lock parent XXX */
+ val = nr64(MIF_CONFIG);
+ val |= MIF_CONFIG_INDIRECT_MODE;
+ nw64(MIF_CONFIG, val);
+
+ phy_id = phy_decode(np->parent->port_phy, np->port);
+ phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+ /* handle different phy types */
+ switch((phy_id & NIU_PHY_ID_MASK)) {
+ case NIU_PHY_ID_MRVL88X2011:
+ err = xcvr_init_10g_mrvl88x2011(np);
+ break;
+
+ default: /* bcom 8704 */
+ err = xcvr_init_10g_bcm8704(np);
+ break;
+ }
+
+ return 0;
+}
+
static int mii_reset(struct niu *np)
{
int limit, err;
@@ -1082,18 +1179,71 @@ static int niu_link_status_common(struct
return 0;
}
-static int link_status_10g(struct niu *np, int *link_up_p)
+static int link_status_10g_mrvl(struct niu *np, int *link_up_p)
{
- unsigned long flags;
- int err, link_up;
+ int err;
+ int link_up = 0;
+ int pma_status;
+ int pcs_status;
- link_up = 0;
- spin_lock_irqsave(&np->lock, flags);
+ err = mdio_read(np, np->phy_addr,
+ MRVL88X2011_USER_DEV1_ADDR, MRVL88X2011_10G_PMD_STATUS_2);
+ if (err < 0) {
+ goto out;
+ }
- err = -EINVAL;
- if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
+ /* Check PMA/PMD Register: 1.0001.2 == 1 */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0) {
goto out;
+ }
+
+ pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1:0);
+
+ /* Check PMC Register : 3.0001.2 == 1: read twice */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0) {
+ goto out;
+ }
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0) {
+ goto out;
+ }
+ pcs_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1:0);
+
+ /* Check XGXS Register : 4.0018.[0-3,12] */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV4_ADDR,
+ MRVL88X2011_10G_XGXS_LANE_STAT);
+ if (err < 0) {
+ goto out;
+ }
+
+ if (err == (
+ PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 |
+ PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 |
+ PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC | 0x800)) {
+
+ link_up = (pma_status && pcs_status) ? 1 : 0;
+ }
+
+ np->link_config.active_speed = SPEED_10000;
+ np->link_config.active_duplex = DUPLEX_FULL;
+ err = 0;
+out:
+ mrvl88x2011_act_led(np, link_up ? MRVL88X2011_LED_CTL_PCS_ACT:MRVL88X2011_LED_CTL_OFF);
+
+ *link_up_p = link_up;
+ return err;
+}
+
+static int link_status_10g_bcom(struct niu *np, int *link_up_p)
+{
+ int err;
+ int link_up = 0;
err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
BCM8704_PMD_RCV_SIGDET);
@@ -1134,12 +1284,42 @@ static int link_status_10g(struct niu *n
err = 0;
out:
- spin_unlock_irqrestore(&np->lock, flags);
-
*link_up_p = link_up;
return err;
}
+static int link_status_10g(struct niu *np, int *link_up_p)
+{
+ unsigned long flags;
+ int err;
+
+ err = -EINVAL;
+
+ spin_lock_irqsave(&np->lock, flags);
+
+ if (np->link_config.loopback_mode == LOOPBACK_DISABLED) {
+ int phy_id;
+
+ phy_id = phy_decode(np->parent->port_phy, np->port);
+ phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+ /* handle different phy types */
+ switch((phy_id & NIU_PHY_ID_MASK)) {
+ case NIU_PHY_ID_MRVL88X2011:
+ err = link_status_10g_mrvl(np, link_up_p);
+ break;
+
+ default: /* bcom 8704 */
+ err = link_status_10g_bcom(np, link_up_p);
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&np->lock, flags);
+
+ return(err);
+}
+
static int link_status_1g(struct niu *np, int *link_up_p)
{
u16 current_speed, bmsr;
@@ -6281,8 +6461,10 @@ static int __devinit phy_record(struct n
if (dev_id_1 < 0 || dev_id_2 < 0)
return 0;
+
if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) {
- if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704)
+ if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) &&
+ ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011))
return 0;
} else {
if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R)
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/net/niu.h linux-2.6-changed/drivers/net/niu.h
--- linux-2.6/drivers/net/niu.h 2007-12-10 14:14:04.000000000 +0100
+++ linux-2.6-changed/drivers/net/niu.h 2008-01-09 14:22:23.000000000 +0100
@@ -2538,6 +2538,39 @@ struct fcram_hash_ipv6 {
#define NIU_PHY_ID_MASK 0xfffff0f0
#define NIU_PHY_ID_BCM8704 0x00206030
#define NIU_PHY_ID_BCM5464R 0x002060b0
+#define NIU_PHY_ID_MRVL88X2011 0x01410020
+
+/* MRVL88X2011 register addresses */
+#define MRVL88X2011_USER_DEV1_ADDR 1
+#define MRVL88X2011_USER_DEV2_ADDR 2
+#define MRVL88X2011_USER_DEV3_ADDR 3
+#define MRVL88X2011_USER_DEV4_ADDR 4
+#define MRVL88X2011_PMA_PMD_CTL_1 0x0000
+#define MRVL88X2011_PMA_PMD_STATUS_1 0x0001
+#define MRVL88X2011_10G_PMD_STATUS_2 0x0008
+#define MRVL88X2011_10G_PMD_TX_DIS 0x0009
+#define MRVL88X2011_10G_XGXS_LANE_STAT 0x0018
+#define MRVL88X2011_GENERAL_CTL 0x8300
+#define MRVL88X2011_LED_BLINK_CTL 0x8303
+#define MRVL88X2011_LED_8_TO_11_CTL 0x8306
+
+/* MRVL88X2011 register control */
+#define MRVL88X2011_ENA_XFPREFCLK 0x0001
+#define MRVL88X2011_ENA_PMDTX 0x0000
+#define MRVL88X2011_LOOPBACK 0x1
+#define MRVL88X2011_LED_ACT 0x1
+#define MRVL88X2011_LNK_STATUS_OK 0x4
+#define MRVL88X2011_LED_BLKRATE_MASK 0x70
+#define MRVL88X2011_LED_BLKRATE_034MS 0x0
+#define MRVL88X2011_LED_BLKRATE_067MS 0x1
+#define MRVL88X2011_LED_BLKRATE_134MS 0x2
+#define MRVL88X2011_LED_BLKRATE_269MS 0x3
+#define MRVL88X2011_LED_BLKRATE_538MS 0x4
+#define MRVL88X2011_LED_CTL_OFF 0x0
+#define MRVL88X2011_LED_CTL_PCS_ACT 0x5
+#define MRVL88X2011_LED_CTL_MASK 0x7
+#define MRVL88X2011_LED(n,v) ((v)<<((n)*4))
+#define MRVL88X2011_LED_STAT(n,v) ((v)>>((n)*4))
#define BCM8704_PMA_PMD_DEV_ADDR 1
#define BCM8704_PCS_DEV_ADDR 2
^ permalink raw reply
* Re: [PATCH] drivers/net/niu: Support for Marvell PHY
From: David Miller @ 2008-01-10 10:24 UTC (permalink / raw)
To: mlindner; +Cc: netdev
In-Reply-To: <1199957581.5290.21.camel@mlindner-lin.skd.de>
From: Mirko Lindner <mlindner@marvell.com>
Date: Thu, 10 Jan 2008 10:33:01 +0100
> This patch makes necessary changes in the Neptune driver to support
> the new Marvell PHY. It also adds support for the LED blinking
> on Neptune cards with Marvell PHY. All registers are using defines
> in the niu.h header file as is already done for the BCM8704 registers.
Applied. Please provide a proper "Signed-off-by: " line next
time as documented in linux/Documentation/SubmittingPatches
Also there were a lot of coding style and other errors. I
fixed them up because I already put you through the ringer
to fix up the original patch.
I'll note most of them, but reading linux/CodingStyle would be a great
idea:
> -static int xcvr_init_10g(struct niu *np)
> +void mrvl88x2011_act_led(struct niu *np, int val)
...
> +void mrvl88x2011_led_blink_rate(struct niu *np, int rate)
> +{
Both of these functions should be marked "static", return an "int" and
check and return all errors indicated by mdio_read() and mdio_write().
> +static int xcvr_init_10g_mrvl88x2011(struct niu *np)
> +{
...
> + /* Set LED functions */
> + mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS);
> + mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF); /* led activity */
Longer than 80-column lines, no error checking.
> + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
> + MRVL88X2011_GENERAL_CTL);
> + if (err < 0) {
> + return(err);
> + }
Extraneous openning and closing braces wasting precious screen
real-estate. "return" is not a function taking an argument, don't
surround simple values with parenthesis.
These happened a lot, I won't mention the other instances.
> + err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
> + MRVL88X2011_GENERAL_CTL, err);
Bad indentation, the argument on the second line of the mdio_write()
call should line up with the initial "np" initial arg on the
previous line.
If necessary, use tools or editors that help do this automatically for
you. Several folks (including me) use Emacs's C mode with coding
style set to "linux" for that purpose.
> +static int xcvr_init_10g(struct niu *np)
> +{
> + int err;
> + u64 val;
> + int phy_id;
Multiple variables of the same type should be on one single line
unless it would make the line too long.
> + /* handle different phy types */
> + switch((phy_id & NIU_PHY_ID_MASK)) {
Space is needed between "switch" keyword and openning parenthesis.
Only one set of parenthesis is sufficient here.
> -static int link_status_10g(struct niu *np, int *link_up_p)
> +static int link_status_10g_mrvl(struct niu *np, int *link_up_p)
> {
> - unsigned long flags;
> - int err, link_up;
> + int err;
> + int link_up = 0;
> + int pma_status;
> + int pcs_status;
No tabs please between variable type and names, and again list
multiple variables of the same type on one single line in order to
save previous screen real-estate.
> + pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1:0);
Spaces are needed to make this easier to read "? 1 : 0".
> + if (err == (
> + PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 |
> + PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 |
> + PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC | 0x800)) {
This "err == (" line should hold the first line of bit values, again
to save lines.
> + mrvl88x2011_act_led(np, link_up ? MRVL88X2011_LED_CTL_PCS_ACT:MRVL88X2011_LED_CTL_OFF);
Line excessively exceeds 80 columns.
> if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) {
> - if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704)
> + if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) &&
> + ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011))
Not indented properly, the second line in the inner "if" statement
should have it's initial parenthesis match up with the second openning
parenthesis on the previous line.
> +/* MRVL88X2011 register control */
> +#define MRVL88X2011_ENA_XFPREFCLK 0x0001
> +#define MRVL88X2011_ENA_PMDTX 0x0000
> +#define MRVL88X2011_LOOPBACK 0x1
> +#define MRVL88X2011_LED_ACT 0x1
> +#define MRVL88X2011_LNK_STATUS_OK 0x4
> +#define MRVL88X2011_LED_BLKRATE_MASK 0x70
> +#define MRVL88X2011_LED_BLKRATE_034MS 0x0
> +#define MRVL88X2011_LED_BLKRATE_067MS 0x1
> +#define MRVL88X2011_LED_BLKRATE_134MS 0x2
> +#define MRVL88X2011_LED_BLKRATE_269MS 0x3
> +#define MRVL88X2011_LED_BLKRATE_538MS 0x4
> +#define MRVL88X2011_LED_CTL_OFF 0x0
> +#define MRVL88X2011_LED_CTL_PCS_ACT 0x5
> +#define MRVL88X2011_LED_CTL_MASK 0x7
> +#define MRVL88X2011_LED(n,v) ((v)<<((n)*4))
> +#define MRVL88X2011_LED_STAT(n,v) ((v)>>((n)*4))
These lines inconsistently use tabs vs. spaces to create the
indentation between the macro name and it's definition.
Anyways, after cleaning up all of that the patch I ended up checking
in looks like the following.
BTW, I just checked in several bug fixes to the Neptune driver
upstream, you might want to check them out.
Thanks.
[NIU]: Support for Marvell PHY
From: Mirko Lindner <mlindner@marvell.com>
This patch makes necessary changes in the Neptune driver to support
the new Marvell PHY. It also adds support for the LED blinking
on Neptune cards with Marvell PHY. All registers are using defines
in the niu.h header file as is already done for the BCM8704 registers.
[ Coding style, etc. cleanups -DaveM ]
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/niu.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++-----
drivers/net/niu.h | 33 ++++++++
2 files changed, 231 insertions(+), 20 deletions(-)
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 9a0c6d3..3bbcea1 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -801,22 +801,90 @@ static int bcm8704_init_user_dev3(struct niu *np)
return 0;
}
-static int xcvr_init_10g(struct niu *np)
+static int mrvl88x2011_act_led(struct niu *np, int val)
+{
+ int err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_8_TO_11_CTL);
+ if (err < 0)
+ return err;
+
+ err &= ~MRVL88X2011_LED(MRVL88X2011_LED_ACT,MRVL88X2011_LED_CTL_MASK);
+ err |= MRVL88X2011_LED(MRVL88X2011_LED_ACT,val);
+
+ return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_8_TO_11_CTL, err);
+}
+
+static int mrvl88x2011_led_blink_rate(struct niu *np, int rate)
+{
+ int err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_BLINK_CTL);
+ if (err >= 0) {
+ err &= ~MRVL88X2011_LED_BLKRATE_MASK;
+ err |= (rate << 4);
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_BLINK_CTL, err);
+ }
+
+ return err;
+}
+
+static int xcvr_init_10g_mrvl88x2011(struct niu *np)
+{
+ int err;
+
+ /* Set LED functions */
+ err = mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS);
+ if (err)
+ return err;
+
+ /* led activity */
+ err = mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF);
+ if (err)
+ return err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_GENERAL_CTL);
+ if (err < 0)
+ return err;
+
+ err |= MRVL88X2011_ENA_XFPREFCLK;
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_GENERAL_CTL, err);
+ if (err < 0)
+ return err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_CTL_1);
+ if (err < 0)
+ return err;
+
+ if (np->link_config.loopback_mode == LOOPBACK_MAC)
+ err |= MRVL88X2011_LOOPBACK;
+ else
+ err &= ~MRVL88X2011_LOOPBACK;
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_CTL_1, err);
+ if (err < 0)
+ return err;
+
+ /* Enable PMD */
+ return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX);
+}
+
+static int xcvr_init_10g_bcm8704(struct niu *np)
{
struct niu_link_config *lp = &np->link_config;
u16 analog_stat0, tx_alarm_status;
int err;
- u64 val;
-
- val = nr64_mac(XMAC_CONFIG);
- val &= ~XMAC_CONFIG_LED_POLARITY;
- val |= XMAC_CONFIG_FORCE_LED_ON;
- nw64_mac(XMAC_CONFIG, val);
-
- /* XXX shared resource, lock parent XXX */
- val = nr64(MIF_CONFIG);
- val |= MIF_CONFIG_INDIRECT_MODE;
- nw64(MIF_CONFIG, val);
err = bcm8704_reset(np);
if (err)
@@ -896,6 +964,38 @@ static int xcvr_init_10g(struct niu *np)
return 0;
}
+static int xcvr_init_10g(struct niu *np)
+{
+ int phy_id, err;
+ u64 val;
+
+ val = nr64_mac(XMAC_CONFIG);
+ val &= ~XMAC_CONFIG_LED_POLARITY;
+ val |= XMAC_CONFIG_FORCE_LED_ON;
+ nw64_mac(XMAC_CONFIG, val);
+
+ /* XXX shared resource, lock parent XXX */
+ val = nr64(MIF_CONFIG);
+ val |= MIF_CONFIG_INDIRECT_MODE;
+ nw64(MIF_CONFIG, val);
+
+ phy_id = phy_decode(np->parent->port_phy, np->port);
+ phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+ /* handle different phy types */
+ switch (phy_id & NIU_PHY_ID_MASK) {
+ case NIU_PHY_ID_MRVL88X2011:
+ err = xcvr_init_10g_mrvl88x2011(np);
+ break;
+
+ default: /* bcom 8704 */
+ err = xcvr_init_10g_bcm8704(np);
+ break;
+ }
+
+ return 0;
+}
+
static int mii_reset(struct niu *np)
{
int limit, err;
@@ -1082,19 +1182,68 @@ static int niu_link_status_common(struct niu *np, int link_up)
return 0;
}
-static int link_status_10g(struct niu *np, int *link_up_p)
+static int link_status_10g_mrvl(struct niu *np, int *link_up_p)
{
- unsigned long flags;
- int err, link_up;
+ int err, link_up, pma_status, pcs_status;
link_up = 0;
- spin_lock_irqsave(&np->lock, flags);
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_10G_PMD_STATUS_2);
+ if (err < 0)
+ goto out;
- err = -EINVAL;
- if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
+ /* Check PMA/PMD Register: 1.0001.2 == 1 */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0)
+ goto out;
+
+ pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);
+
+ /* Check PMC Register : 3.0001.2 == 1: read twice */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0)
+ goto out;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0)
+ goto out;
+
+ pcs_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);
+
+ /* Check XGXS Register : 4.0018.[0-3,12] */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV4_ADDR,
+ MRVL88X2011_10G_XGXS_LANE_STAT);
+ if (err < 0)
goto out;
+ if (err == (PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 |
+ PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 |
+ PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC |
+ 0x800))
+ link_up = (pma_status && pcs_status) ? 1 : 0;
+
+ np->link_config.active_speed = SPEED_10000;
+ np->link_config.active_duplex = DUPLEX_FULL;
+ err = 0;
+out:
+ mrvl88x2011_act_led(np, (link_up ?
+ MRVL88X2011_LED_CTL_PCS_ACT :
+ MRVL88X2011_LED_CTL_OFF));
+
+ *link_up_p = link_up;
+ return err;
+}
+
+static int link_status_10g_bcom(struct niu *np, int *link_up_p)
+{
+ int err, link_up;
+
+ link_up = 0;
+
err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
BCM8704_PMD_RCV_SIGDET);
if (err < 0)
@@ -1134,9 +1283,37 @@ static int link_status_10g(struct niu *np, int *link_up_p)
err = 0;
out:
+ *link_up_p = link_up;
+ return err;
+}
+
+static int link_status_10g(struct niu *np, int *link_up_p)
+{
+ unsigned long flags;
+ int err = -EINVAL;
+
+ spin_lock_irqsave(&np->lock, flags);
+
+ if (np->link_config.loopback_mode == LOOPBACK_DISABLED) {
+ int phy_id;
+
+ phy_id = phy_decode(np->parent->port_phy, np->port);
+ phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+ /* handle different phy types */
+ switch (phy_id & NIU_PHY_ID_MASK) {
+ case NIU_PHY_ID_MRVL88X2011:
+ err = link_status_10g_mrvl(np, link_up_p);
+ break;
+
+ default: /* bcom 8704 */
+ err = link_status_10g_bcom(np, link_up_p);
+ break;
+ }
+ }
+
spin_unlock_irqrestore(&np->lock, flags);
- *link_up_p = link_up;
return err;
}
@@ -6297,7 +6474,8 @@ static int __devinit phy_record(struct niu_parent *parent,
if (dev_id_1 < 0 || dev_id_2 < 0)
return 0;
if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) {
- if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704)
+ if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) &&
+ ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011))
return 0;
} else {
if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R)
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index 10e3f11..0e8626a 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -2538,6 +2538,39 @@ struct fcram_hash_ipv6 {
#define NIU_PHY_ID_MASK 0xfffff0f0
#define NIU_PHY_ID_BCM8704 0x00206030
#define NIU_PHY_ID_BCM5464R 0x002060b0
+#define NIU_PHY_ID_MRVL88X2011 0x01410020
+
+/* MRVL88X2011 register addresses */
+#define MRVL88X2011_USER_DEV1_ADDR 1
+#define MRVL88X2011_USER_DEV2_ADDR 2
+#define MRVL88X2011_USER_DEV3_ADDR 3
+#define MRVL88X2011_USER_DEV4_ADDR 4
+#define MRVL88X2011_PMA_PMD_CTL_1 0x0000
+#define MRVL88X2011_PMA_PMD_STATUS_1 0x0001
+#define MRVL88X2011_10G_PMD_STATUS_2 0x0008
+#define MRVL88X2011_10G_PMD_TX_DIS 0x0009
+#define MRVL88X2011_10G_XGXS_LANE_STAT 0x0018
+#define MRVL88X2011_GENERAL_CTL 0x8300
+#define MRVL88X2011_LED_BLINK_CTL 0x8303
+#define MRVL88X2011_LED_8_TO_11_CTL 0x8306
+
+/* MRVL88X2011 register control */
+#define MRVL88X2011_ENA_XFPREFCLK 0x0001
+#define MRVL88X2011_ENA_PMDTX 0x0000
+#define MRVL88X2011_LOOPBACK 0x1
+#define MRVL88X2011_LED_ACT 0x1
+#define MRVL88X2011_LNK_STATUS_OK 0x4
+#define MRVL88X2011_LED_BLKRATE_MASK 0x70
+#define MRVL88X2011_LED_BLKRATE_034MS 0x0
+#define MRVL88X2011_LED_BLKRATE_067MS 0x1
+#define MRVL88X2011_LED_BLKRATE_134MS 0x2
+#define MRVL88X2011_LED_BLKRATE_269MS 0x3
+#define MRVL88X2011_LED_BLKRATE_538MS 0x4
+#define MRVL88X2011_LED_CTL_OFF 0x0
+#define MRVL88X2011_LED_CTL_PCS_ACT 0x5
+#define MRVL88X2011_LED_CTL_MASK 0x7
+#define MRVL88X2011_LED(n,v) ((v)<<((n)*4))
+#define MRVL88X2011_LED_STAT(n,v) ((v)>>((n)*4))
#define BCM8704_PMA_PMD_DEV_ADDR 1
#define BCM8704_PCS_DEV_ADDR 2
--
1.5.4.rc2.84.gf85fd
^ permalink raw reply related
* [PATCH][NEIGH] Fix race between neigh_parms_release and neightbl_fill_parms
From: Pavel Emelyanov @ 2008-01-10 10:56 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
The neightbl_fill_parms() is called under the write-locked
tbl->lock and accesses the parms->dev. The negh_parm_release()
calls the dev_put(parms->dev) without this lock. This
creates a tiny race window on which the parms contains
potentially stale dev pointer.
To fix this race it's enough to move the dev_put() upper
under the tbl->lock, but note, that the parms are held by
neighbors and thus can live after the neigh_parms_release()
is called, so we still can have a parm with bad dev pointer.
I didn't find where the neigh->parms->dev is accessed, but
still think that putting the dev is to be done in a place,
where the parms are really freed. Am I right with that?
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 29b8ee4..cc8a2f1 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1316,8 +1316,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
*p = parms->next;
parms->dead = 1;
write_unlock_bh(&tbl->lock);
- if (parms->dev)
- dev_put(parms->dev);
call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
return;
}
@@ -1328,6 +1326,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
void neigh_parms_destroy(struct neigh_parms *parms)
{
+ if (parms->dev)
+ dev_put(parms->dev);
kfree(parms);
}
^ permalink raw reply related
* Re: No idea about shaping trough many pc
From: Denys Fedoryshchenko @ 2008-01-10 11:00 UTC (permalink / raw)
To: Badalian Vyacheslav, netdev
In-Reply-To: <4785E01B.3080900@bigtelecom.ru>
For proper link bandwidth sharing i guess something like network counters
have to be shared between PC's (with proper locking). I didn't heard anything
like this
IMHO a ways to do this:
Split destination network to multiple parts and do routes on Cisco. Let's say
you have:
192.168.0.0/16
and u have 4 balancing PC's
total bandwidth 1Gbit/s (speed conforming to IEC 1000Mbit/s in 1Gbit/s)
Then u do on cisco :
192.168.0.0/18 via PC1(shared speed 250Mbit/s)
192.168.64.0/18 via PC2(shared speed 250Mbit/s)
192.168.128.0/18 via PC3(shared speed 250Mbit/s)
192.168.192.0/18 via PC4(shared speed 250Mbit/s)
Probably you can do some scripts to check, if there is in some PC too much
available bandwidth (average 5 minutes), then you can give some other PC
which is need more bandwidth - more bandwidth. For example:
Average counters for 5minute shows:
PC1 - occupy 100Mbit/s
PC2 - -//- 50Mbit/s
PC3 - -//- 150Mbit/s
PC4 - -//- 230Mbit/s
Then u change link speed:
PC1 max 200
PC2 max 150
PC3 max 250
PC4 max 400 (100 from PC2 and 50 from PC1)
Sure PC must be capable to pass this traffic. And my IMHO it is not normal
that your PC's not able to handle more than 200Mbps of traffic. I have
complicated setup, with 4 LAN 8139 cards, which is passing totally 200Mbps
traffic. I am sure it can handle up to 300mbps, but already i am changing it
to PC with PCI-E e1000/broadcom netxtreme with offloading capabilities, large
buffers and proper drivers with NAPI. I have such hardware handling now for
example 160Mbps and counters is:
12:50:41 CPU %user %nice %sys %iowait %irq %soft %steal
%idle intr/s
12:50:42 all 0.00 0.00 0.00 0.00 0.25 1.24 0.00
98.51 4009.90
12:50:43 all 0.00 0.00 0.00 0.00 0.00 1.25 0.00
98.75 4024.75
12:50:44 all 0.00 0.00 0.00 0.00 0.00 1.50 0.00
98.50 4181.82
12:50:45 all 0.25 0.00 0.00 0.00 0.00 1.50 0.00
98.25 4626.73
12:50:46 all 0.00 0.00 0.00 0.00 0.00 1.50 0.00
98.50 4351.52
12:50:47 all 0.25 0.00 0.00 0.00 0.00 1.75 0.00
98.00 4805.88
It is 2.6.23.8 with some mistakes during configuration, i am doing to try
2.6.24-rc7 and some optimizations.
Right now profile looks like:
10957 17.0675 mwait_idle_with_hints
7454 11.6110 read_hpet
3883 6.0485 _raw_spin_lock
1605 2.5001 timer_interrupt
1363 2.1231 irq_entries_start
So maybe i will have to try change timers to TSC, disable nmi_watchdog and
try to tune up network driver (bnx2).
Probably you have to check such things too.
On Thu, 10 Jan 2008 12:06:35 +0300, Badalian Vyacheslav wrote
> Hello all.
> I try more then 2 month resolve problem witch my shaping. Maybe you
> can help for me?
>
> Sheme:
> +-------------------+
> + ----- | Shaping PC 1 | ---------+
> / +-------------------+ \
> +--------+ / +--------------------+ \
> + --------+ | Cisco | +-------- | Shaping PC N | -----------+ --
> ---| CISCO | +--------+ \ +--------------------+
> / +---------+ \ +---------
> ------------+ / + ----- | Shaping PC
> 20 | --------+ +---------------------+
>
> Network - Over 10k users. Common bandwidth to INTERNET more then 1
> GBs All computers have BGP and turn on multipath. Cisco can't do
> load sharing by Packet (its can resolve all my problems =((( ). Only
> by DST IP, SRC IP, or +Level4. Ok. User must have speed 1mbs. Lets
> look variants:
> 1. Create rules to user = (1mbs/N computers). If user use N
> connection all great, but if it use 1 connection his speed = 1mbs/N -
> its not look good. All be great if cisco can PER PACKET load
> sharing =(
> 2. Create rules to user = 1mbs. If user use 1 connection all great,
> but if it use N connection his speed much more then needed limit =(
>
> Why i use 20 PC? Becouse 1 pc normal forward 100-150mbs... when it
> have 100% cpu usage on Sofware Interrupts...
>
> Any idea how to resolve this problem?
>
> In my dreams (feature request to netdev ;) ):
> Get PC - title: MASTER TC. All 20 PC syncronize statistic with
> MASTER and have common rules and statistic. Then i use variant 2 and
> will be happy... but its not real? =( Maybe have other variants?
>
> Thanks for help!
> Slavon.
> P.S. Sorry for my english =(
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Denys Fedoryshchenko
Technical Manager
Virtual ISP S.A.L.
^ permalink raw reply
* Re: [patch net-2.6.25 00/10][NETNS][IPV6] make sysctl per namespace - V3
From: David Miller @ 2008-01-10 11:15 UTC (permalink / raw)
To: dlezcano; +Cc: netdev, benjamin.thery
In-Reply-To: <20080109164533.695191040@localhost.localdomain>
From: Daniel Lezcano <dlezcano@fr.ibm.com>
Date: Wed, 09 Jan 2008 17:45:33 +0100
> The following patchset makes the ipv6 sysctl to handle multiple
> network namespaces. Each instance of a network namespace as its own
> set of sysctl values, that means the behavior of the ipv6 stack can be
> different depending on the sysctl values setup in the different
> network namespaces.
I applied all of this to net-2.6.25 but what a rough half hour
it was :-/
Starting at patch #5 there were tons of "space before tab" errors.
And as I fixed them up, this made subsequent patches need rediffing
since the contextual lines in patches after #5 needed the whitespace
fixed up as well.
I didn't push this back to you because this was already the 3rd round,
but please show me some love and check this stuff out before
submission. GIT gives you effective ways to verify the whitespace
without even applying the patch.
~davem/bin/pcheck:
#!/bin/sh
set -x
git apply --check --whitespace=error-all $1
^ permalink raw reply
* Re: Linux IPv6 DAD not full conform to RFC 4862 ?
From: Karsten Keil @ 2008-01-10 11:16 UTC (permalink / raw)
To: netdev
In-Reply-To: <20080109202653.GA26160@pingi.kke.suse.de>
Hi,
On Wed, Jan 09, 2008 at 09:26:53PM +0100, Karsten Keil wrote:
> >
> > Reading the section you reference, we do follow all the MUST requirements, and
> > we log an error. Given that the disable section is a SHOULD, I think we can at
> > least be somewhat more restrictive in our implementation. Perhaps we should
> > just disable the interface iff the failed address is link-local AND there are no
> > other functional address assigned to the interface.
>
> I agree here, but it seems that currently the IPv6 Logo Committee thinks
> that it has to be disable the interface to get the IPv6 ready Logo in
> future. I already claim that on a discussion at the TAHI users list.
>
JFYI, here the answer from the TAHI list.
Hi, Karsten.
Thanks for your comments.
I know that it is SHOULD,
but our test tool supports the test specification
published by IPv6 Ready Logo Program <http://www.ipv6ready.org/>,
and basically the test specification supports all of MUST and SHOULD.
You may know,
now IPv6 Ready Logo Committee is also discussing
about the next major revision up of test specification.
RFC 4862 Section 5.4.5 is one of discussing point.
The public review has been over,
but if you have strong concern about it,
I recommend to comment to <ipv6ready-info@ipv6ready.org>.
Personally,
I think that mandating this function is the best way.
But vendor's input will really important for them.
Regards,
Yukiyo Akisada
So it would be good if some of the networking experts complain there.
--
Karsten Keil
SuSE Labs
ISDN and VOIP development
SUSE LINUX Products GmbH, Maxfeldstr.5 90409 Nuernberg, GF: Markus Rex, HRB 16746 (AG Nuernberg)
^ permalink raw reply
* Re: No idea about shaping trough many pc
From: Badalian Vyacheslav @ 2008-01-10 11:23 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev
In-Reply-To: <20080110103708.M15442@visp.net.lb>
Thanks for answer!
1 PC have more then 15k TC rules.... tc get many cpu si...
I don't wont split networks on cisco, becouse i need HA. If PC do
shutdown - another must get all function. BGP work great for this solution.
But have troubles in control common traffic from users.
Will be great if i can create common TC rules that share to all PC and
its have common data (statistic, info, tokens, and e.t.c.). Maybe netdev
think about system mode that we have one OS on many PC (Like HA
Cluster). Linux may do great routing solution!
Will be great if all 20 PC may be 1 logical PC that have many CPU and
may process lots of interrupts!
Thanks =)
> For proper link bandwidth sharing i guess something like network counters
> have to be shared between PC's (with proper locking). I didn't heard anything
> like this
>
> IMHO a ways to do this:
> Split destination network to multiple parts and do routes on Cisco. Let's say
> you have:
> 192.168.0.0/16
> and u have 4 balancing PC's
> total bandwidth 1Gbit/s (speed conforming to IEC 1000Mbit/s in 1Gbit/s)
>
> Then u do on cisco :
> 192.168.0.0/18 via PC1(shared speed 250Mbit/s)
> 192.168.64.0/18 via PC2(shared speed 250Mbit/s)
> 192.168.128.0/18 via PC3(shared speed 250Mbit/s)
> 192.168.192.0/18 via PC4(shared speed 250Mbit/s)
>
> Probably you can do some scripts to check, if there is in some PC too much
> available bandwidth (average 5 minutes), then you can give some other PC
> which is need more bandwidth - more bandwidth. For example:
>
> Average counters for 5minute shows:
> PC1 - occupy 100Mbit/s
> PC2 - -//- 50Mbit/s
> PC3 - -//- 150Mbit/s
> PC4 - -//- 230Mbit/s
>
> Then u change link speed:
> PC1 max 200
> PC2 max 150
> PC3 max 250
> PC4 max 400 (100 from PC2 and 50 from PC1)
>
> Sure PC must be capable to pass this traffic. And my IMHO it is not normal
> that your PC's not able to handle more than 200Mbps of traffic. I have
> complicated setup, with 4 LAN 8139 cards, which is passing totally 200Mbps
> traffic. I am sure it can handle up to 300mbps, but already i am changing it
> to PC with PCI-E e1000/broadcom netxtreme with offloading capabilities, large
> buffers and proper drivers with NAPI. I have such hardware handling now for
> example 160Mbps and counters is:
> 12:50:41 CPU %user %nice %sys %iowait %irq %soft %steal
> %idle intr/s
> 12:50:42 all 0.00 0.00 0.00 0.00 0.25 1.24 0.00
> 98.51 4009.90
> 12:50:43 all 0.00 0.00 0.00 0.00 0.00 1.25 0.00
> 98.75 4024.75
> 12:50:44 all 0.00 0.00 0.00 0.00 0.00 1.50 0.00
> 98.50 4181.82
> 12:50:45 all 0.25 0.00 0.00 0.00 0.00 1.50 0.00
> 98.25 4626.73
> 12:50:46 all 0.00 0.00 0.00 0.00 0.00 1.50 0.00
> 98.50 4351.52
> 12:50:47 all 0.25 0.00 0.00 0.00 0.00 1.75 0.00
> 98.00 4805.88
>
> It is 2.6.23.8 with some mistakes during configuration, i am doing to try
> 2.6.24-rc7 and some optimizations.
>
> Right now profile looks like:
> 10957 17.0675 mwait_idle_with_hints
> 7454 11.6110 read_hpet
> 3883 6.0485 _raw_spin_lock
> 1605 2.5001 timer_interrupt
> 1363 2.1231 irq_entries_start
>
> So maybe i will have to try change timers to TSC, disable nmi_watchdog and
> try to tune up network driver (bnx2).
> Probably you have to check such things too.
>
> On Thu, 10 Jan 2008 12:06:35 +0300, Badalian Vyacheslav wrote
>
>> Hello all.
>> I try more then 2 month resolve problem witch my shaping. Maybe you
>> can help for me?
>>
>> Sheme:
>> +-------------------+
>> + ----- | Shaping PC 1 | ---------+
>> / +-------------------+ \
>> +--------+ / +--------------------+ \
>> + --------+ | Cisco | +-------- | Shaping PC N | -----------+ --
>> ---| CISCO | +--------+ \ +--------------------+
>> / +---------+ \ +---------
>> ------------+ / + ----- | Shaping PC
>> 20 | --------+ +---------------------+
>>
>> Network - Over 10k users. Common bandwidth to INTERNET more then 1
>> GBs All computers have BGP and turn on multipath. Cisco can't do
>> load sharing by Packet (its can resolve all my problems =((( ). Only
>> by DST IP, SRC IP, or +Level4. Ok. User must have speed 1mbs. Lets
>> look variants:
>> 1. Create rules to user = (1mbs/N computers). If user use N
>> connection all great, but if it use 1 connection his speed = 1mbs/N -
>> its not look good. All be great if cisco can PER PACKET load
>> sharing =(
>> 2. Create rules to user = 1mbs. If user use 1 connection all great,
>> but if it use N connection his speed much more then needed limit =(
>>
>> Why i use 20 PC? Becouse 1 pc normal forward 100-150mbs... when it
>> have 100% cpu usage on Sofware Interrupts...
>>
>> Any idea how to resolve this problem?
>>
>> In my dreams (feature request to netdev ;) ):
>> Get PC - title: MASTER TC. All 20 PC syncronize statistic with
>> MASTER and have common rules and statistic. Then i use variant 2 and
>> will be happy... but its not real? =( Maybe have other variants?
>>
>> Thanks for help!
>> Slavon.
>> P.S. Sorry for my english =(
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
>
> --
> Denys Fedoryshchenko
> Technical Manager
> Virtual ISP S.A.L.
>
>
>
^ permalink raw reply
* [PATCH 2.6.25] [ATM] Oops reading net/atm/arp
From: Denis V. Lunev @ 2008-01-10 11:28 UTC (permalink / raw)
To: davem; +Cc: dlezcano, xemul, netdev, containers, devel
cat /proc/net/atm/arp causes the NULL pointer dereference in the
get_proc_net+0xc/0x3a. This happens as proc_get_net believes that the
parent proc dir entry contains struct net.
Fix this assumption for "net/atm" case.
The problem is introduced by the commit c0097b07abf5f92ab135d024dd41bd2aada1512f
from Eric W. Biederman/Daniel Lezcano.
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index cfc4f6c..4823c96 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -96,6 +96,17 @@ static struct proc_dir_entry *proc_net_shadow(struct task_struct *task,
return task->nsproxy->net_ns->proc_net;
}
+struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
+ struct proc_dir_entry *parent)
+{
+ struct proc_dir_entry *pde;
+ pde = proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
+ if (pde != NULL)
+ pde->data = net;
+ return pde;
+}
+EXPORT_SYMBOL_GPL(proc_net_mkdir);
+
static __net_init int proc_net_ns_init(struct net *net)
{
struct proc_dir_entry *root, *netd, *net_statd;
@@ -107,18 +118,16 @@ static __net_init int proc_net_ns_init(struct net *net)
goto out;
err = -EEXIST;
- netd = proc_mkdir("net", root);
+ netd = proc_net_mkdir(net, "net", root);
if (!netd)
goto free_root;
err = -EEXIST;
- net_statd = proc_mkdir("stat", netd);
+ net_statd = proc_net_mkdir(net, "stat", netd);
if (!net_statd)
goto free_net;
root->data = net;
- netd->data = net;
- net_statd->data = net;
net->proc_net_root = root;
net->proc_net = netd;
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index a531682..8f92546 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -201,6 +201,8 @@ static inline struct proc_dir_entry *create_proc_info_entry(const char *name,
extern struct proc_dir_entry *proc_net_fops_create(struct net *net,
const char *name, mode_t mode, const struct file_operations *fops);
extern void proc_net_remove(struct net *net, const char *name);
+extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
+ struct proc_dir_entry *parent);
#else
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 5d9d5ff..565e75e 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -476,7 +476,7 @@ static void atm_proc_dirs_remove(void)
if (e->dirent)
remove_proc_entry(e->name, atm_proc_root);
}
- remove_proc_entry("atm", init_net.proc_net);
+ proc_net_remove(&init_net, "atm");
}
int __init atm_proc_init(void)
@@ -484,7 +484,7 @@ int __init atm_proc_init(void)
static struct atm_proc_entry *e;
int ret;
- atm_proc_root = proc_mkdir("atm", init_net.proc_net);
+ atm_proc_root = proc_net_mkdir(&init_net, "atm", init_net.proc_net);
if (!atm_proc_root)
goto err_out;
for (e = atm_proc_ents; e->name; e++) {
^ permalink raw reply related
* [PATCH 2.6.25] [ATM] Simplify /proc/net/atm/arp opening
From: Denis V. Lunev @ 2008-01-10 11:30 UTC (permalink / raw)
To: davem; +Cc: dlezcano, xemul, netdev, containers, devel
The iterator state->ns.neigh_sub_iter initialization is moved from
arp_seq_open to clip_seq_start for convinience. This should not be a problem
as the iterator will be used only after the seq_start callback.
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 47fbdc0..de5b780 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -903,6 +903,8 @@ static void *clip_seq_sub_iter(struct neigh_seq_state *_state,
static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
{
+ struct clip_seq_state *state = seq->private;
+ state->ns.neigh_sub_iter = clip_seq_sub_iter;
return neigh_seq_start(seq, pos, &clip_tbl, NEIGH_SEQ_NEIGH_ONLY);
}
@@ -932,49 +934,15 @@ static const struct seq_operations arp_seq_ops = {
static int arp_seq_open(struct inode *inode, struct file *file)
{
- struct clip_seq_state *state;
- struct seq_file *seq;
- int rc = -EAGAIN;
-
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (!state) {
- rc = -ENOMEM;
- goto out_kfree;
- }
- state->ns.neigh_sub_iter = clip_seq_sub_iter;
-
- rc = seq_open(file, &arp_seq_ops);
- if (rc)
- goto out_kfree;
-
- seq = file->private_data;
- seq->private = state;
- state->ns.net = get_proc_net(inode);
- if (!state->ns.net) {
- seq_release_private(inode, file);
- rc = -ENXIO;
- }
-out:
- return rc;
-
-out_kfree:
- kfree(state);
- goto out;
-}
-
-static int arp_seq_release(struct inode *inode, struct file *file)
-{
- struct seq_file *seq = file->private_data;
- struct clip_seq_state *state = seq->private;
- put_net(state->ns.net);
- return seq_release_private(inode, file);
+ return seq_open_net(inode, file, &arp_seq_ops,
+ sizeof(struct clip_seq_state));
}
static const struct file_operations arp_seq_fops = {
.open = arp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = arp_seq_release,
+ .release = seq_release_net,
.owner = THIS_MODULE
};
#endif
^ permalink raw reply related
* [PATCH 2.6.25] [NEIGH] Make /proc/net/arp opening consistent with seq_net_open semantics
From: Denis V. Lunev @ 2008-01-10 11:32 UTC (permalink / raw)
To: davem; +Cc: dlezcano, xemul, netdev, containers, devel
seq_open_net requires that first field of the seq->private data to be
struct seq_net_private. In reality this is a single pointer to a struct net
for now. The patch makes code consistent.
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index a9dda29..09f9fc6 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -223,7 +223,7 @@ extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct n
extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
struct neigh_seq_state {
- struct net *net;
+ struct seq_net_private p;
struct neigh_table *tbl;
void *(*neigh_sub_iter)(struct neigh_seq_state *state,
struct neighbour *n, loff_t *pos);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 8024933..19c0dd1 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2142,7 +2142,7 @@ EXPORT_SYMBOL(__neigh_for_each_release);
static struct neighbour *neigh_get_first(struct seq_file *seq)
{
struct neigh_seq_state *state = seq->private;
- struct net *net = state->net;
+ struct net *net = state->p.net;
struct neigh_table *tbl = state->tbl;
struct neighbour *n = NULL;
int bucket = state->bucket;
@@ -2183,7 +2183,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
loff_t *pos)
{
struct neigh_seq_state *state = seq->private;
- struct net *net = state->net;
+ struct net *net = state->p.net;
struct neigh_table *tbl = state->tbl;
if (state->neigh_sub_iter) {
@@ -2243,7 +2243,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
{
struct neigh_seq_state *state = seq->private;
- struct net * net = state->net;
+ struct net * net = state->p.net;
struct neigh_table *tbl = state->tbl;
struct pneigh_entry *pn = NULL;
int bucket = state->bucket;
@@ -2266,7 +2266,7 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
loff_t *pos)
{
struct neigh_seq_state *state = seq->private;
- struct net * net = state->net;
+ struct net * net = state->p.net;
struct neigh_table *tbl = state->tbl;
pn = pn->next;
^ permalink raw reply related
* Re: Linux IPv6 DAD not full conform to RFC 4862 ?
From: Karsten Keil @ 2008-01-10 11:29 UTC (permalink / raw)
To: netdev
In-Reply-To: <20080109.153212.144388472.davem@davemloft.net>
On Wed, Jan 09, 2008 at 03:32:12PM -0800, David Miller wrote:
> From: Karsten Keil <kkeil@suse.de>
> Date: Wed, 9 Jan 2008 16:36:56 +0100
>
> > If the address is a link-local address formed from an interface
> > identifier based on the hardware address, which is supposed to be
> > uniquely assigned (e.g., EUI-64 for an Ethernet interface), IP
> > operation on the interface SHOULD be disabled. By disabling IP
> > operation, the node will then:
> >
> > - not send any IP packets from the interface,
> >
> > - silently drop any IP packets received on the interface, and
> >
> > - not forward any IP packets to the interface (when acting as a
> > router or processing a packet with a Routing header).
>
> I question any RFC mandate that shuts down IP communication on a node
> because of packets received from remote systems.
>
> If the TAHI test can trigger this, so can a compromised system on your
> network and won't that be fun? :-)
I agree, but on the other side, a interface with a real duplicate HW address
sending packets on the network can also cause very serious problems, and
maybe is not so easy to detect as a system where the interface never come
up because of this. So maybe it makes sense to implement it as option, not
as default.
And the DOS scenario is already here, also without disabling IP completely,
since you can deny any IPv6 address assignments with faked DAD pakets.
--
Karsten Keil
SuSE Labs
SUSE LINUX Products GmbH, Maxfeldstr.5 90409 Nuernberg, GF: Markus Rex, HRB 16746 (AG Nuernberg)
^ permalink raw reply
* Re: FW: ccid2/ccid3 oopses
From: Gerrit Renker @ 2008-01-10 11:31 UTC (permalink / raw)
To: devzero; +Cc: Arnaldo Carvalho de Melo, dccp, netdev
In-Reply-To: <95473050@web.de>
| > So maybe the cause triggering this oops is somewhere else.
|
| yes, probably. sorry - i didn`t tell or maybe i didn`t know when writing
| my first mail to module authors and forget to add that before forwarding here.
|
| for me , the problem does not happen with suse kernel of the day
| (2.6.24-rc6-git7-20080102160500-default, .config attached) but it happens
| with vanilla 2.6.24-rc6 (mostly allmodconfig, also attached)
|
There are 256 differences between the two .config files. I think there are other
people on the list who will be able to give more information regarding the .config
files. The differences that struck me in the one which doesn't work is
-- CONFIG_DEBUG_KERNEL and
-- CONFIG_DEBUG_BUGVERBOSE were not set. Both are very useful for bug-hunting,
the latter is much better for decoding oopses.
Can't say anything about the Suse kernel. We use the plain kernel from www.kernel.org,
specifically the netdev-tree:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
If you can't get further here, try with a kernel.org kernel or check Suse forums.
1. the tests yesterday were done on the DCCP test tree based on the above netdev-2.6
2.6.24-rc7 tree from git://eden-feed.erg.abdn.ac.uk/dccp_exp (dccp subtree)
Tested your for-loop 60 seconds each for CCID3/4 -- no oops.
2. also repeated the tests on an unmodified 2.6.24-rc7 tree from netdev-2.6 (today)
120 seconds for-loop each -- no oops.
As said, if the above does not help, try a www.kernel.org kernel (or one of the
above trees) first.
|
| >| > >> the easiest way to reproduce is:
| > | > >>
| > | > >> while true;do modprobe dccp_ccid2/3;modprobe -r dccp_ccid2/3;done
| > | > >> after short time, the kernel oopses (messages below)
| > | > >>
^ permalink raw reply
* Re: [PATCH netns-2.6.25 0/19] routing virtualization v2
From: David Miller @ 2008-01-10 11:38 UTC (permalink / raw)
To: den; +Cc: benjamin.thery, dlezcano, devel, containers, netdev, xemul
In-Reply-To: <47850C57.60907@openvz.org>
From: "Denis V. Lunev" <den@openvz.org>
Date: Wed, 09 Jan 2008 21:03:03 +0300
> This set adds namespace support for routing tables & rules
> manipulation in the different namespaces. So, one could create a
> namespace and setup IPv4 routing there how he wants.
All 19 patches applied, thanks Denis.
^ permalink raw reply
* Re: [PATCH][NEIGH] Fix race between neigh_parms_release and neightbl_fill_parms
From: David Miller @ 2008-01-10 11:50 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel
In-Reply-To: <4785F9F5.6070502@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 10 Jan 2008 13:56:53 +0300
> The neightbl_fill_parms() is called under the write-locked
> tbl->lock and accesses the parms->dev. The negh_parm_release()
> calls the dev_put(parms->dev) without this lock. This
> creates a tiny race window on which the parms contains
> potentially stale dev pointer.
>
> To fix this race it's enough to move the dev_put() upper
> under the tbl->lock, but note, that the parms are held by
> neighbors and thus can live after the neigh_parms_release()
> is called, so we still can have a parm with bad dev pointer.
>
> I didn't find where the neigh->parms->dev is accessed, but
> still think that putting the dev is to be done in a place,
> where the parms are really freed. Am I right with that?
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
It is accessed in lookup_neigh_parms(), neightbl_fill_parms(), and
neightbl_fill_info() (hmmm, that BUG_ON(tbl->parms.dev) is cute).
You fix looks correct, patch applied, thanks!
^ permalink raw reply
* Re: [PATCH 2.6.25] [ATM] Oops reading net/atm/arp
From: David Miller @ 2008-01-10 11:51 UTC (permalink / raw)
To: den; +Cc: dlezcano, xemul, netdev, containers, devel
In-Reply-To: <20080110112853.GA16173@iris.sw.ru>
From: "Denis V. Lunev" <den@openvz.org>
Date: Thu, 10 Jan 2008 14:28:53 +0300
> cat /proc/net/atm/arp causes the NULL pointer dereference in the
> get_proc_net+0xc/0x3a. This happens as proc_get_net believes that the
> parent proc dir entry contains struct net.
>
> Fix this assumption for "net/atm" case.
>
> The problem is introduced by the commit c0097b07abf5f92ab135d024dd41bd2aada1512f
> from Eric W. Biederman/Daniel Lezcano.
>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 2.6.25] [ATM] Simplify /proc/net/atm/arp opening
From: David Miller @ 2008-01-10 11:52 UTC (permalink / raw)
To: den; +Cc: dlezcano, xemul, netdev, containers, devel
In-Reply-To: <20080110113044.GA16213@iris.sw.ru>
From: "Denis V. Lunev" <den@openvz.org>
Date: Thu, 10 Jan 2008 14:30:44 +0300
> The iterator state->ns.neigh_sub_iter initialization is moved from
> arp_seq_open to clip_seq_start for convinience. This should not be a problem
> as the iterator will be used only after the seq_start callback.
>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 2.6.25] [NEIGH] Make /proc/net/arp opening consistent with seq_net_open semantics
From: David Miller @ 2008-01-10 11:53 UTC (permalink / raw)
To: den; +Cc: dlezcano, xemul, netdev, containers, devel
In-Reply-To: <20080110113219.GA16233@iris.sw.ru>
From: "Denis V. Lunev" <den@openvz.org>
Date: Thu, 10 Jan 2008 14:32:19 +0300
> seq_open_net requires that first field of the seq->private data to be
> struct seq_net_private. In reality this is a single pointer to a struct net
> for now. The patch makes code consistent.
>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
Applied, thanks for correcting this.
^ permalink raw reply
* Re: [NET] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
From: David Miller @ 2008-01-10 11:56 UTC (permalink / raw)
To: dada1; +Cc: herbert, paulmck, dipankar, netdev
In-Reply-To: <20080109113727.50eae500.dada1@cosmosbay.com>
From: Eric Dumazet <dada1@cosmosbay.com>
Date: Wed, 9 Jan 2008 11:37:27 +0100
> [NET] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
>
> In rt_cache_get_next(), no need to guard seq->private by a rcu_dereference()
> since seq is private to the thread running this function. Reading seq.private
> once (as guaranted bu rcu_dereference()) or several time if compiler really is
> dumb enough wont change the result.
>
> But we miss real spots where rcu_dereference() are needed, both in
> rt_cache_get_first() and rt_cache_get_next()
>
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
I've applied this to net-2.6, thanks!
^ permalink raw reply
* Re: [PATCH v3] AX25: kill user triggable printks
From: David Miller @ 2008-01-10 11:58 UTC (permalink / raw)
To: max; +Cc: netdev
In-Reply-To: <1199874070-9524-1-git-send-email-max@stro.at>
From: maximilian attems <max@stro.at>
Date: Wed, 9 Jan 2008 11:21:10 +0100
> sfuzz can easily trigger any of those.
>
> move the printk message to the corresponding comment:
> makes the intention of the code clear and easy
> to pick up on an scheduled removal.
> as bonus simplify the braces placement.
>
> Signed-off-by: maximilian attems <max@stro.at>
Applied, thanks.
^ permalink raw reply
* Re: [patch net-2.6.25 00/10][NETNS][IPV6] make sysctl per namespace - V3
From: Daniel Lezcano @ 2008-01-10 11:52 UTC (permalink / raw)
To: David Miller; +Cc: netdev, benjamin.thery
In-Reply-To: <20080110.031544.259471083.davem@davemloft.net>
David Miller wrote:
> From: Daniel Lezcano <dlezcano@fr.ibm.com>
> Date: Wed, 09 Jan 2008 17:45:33 +0100
>
>> The following patchset makes the ipv6 sysctl to handle multiple
>> network namespaces. Each instance of a network namespace as its own
>> set of sysctl values, that means the behavior of the ipv6 stack can be
>> different depending on the sysctl values setup in the different
>> network namespaces.
>
> I applied all of this to net-2.6.25 but what a rough half hour
> it was :-/
>
> Starting at patch #5 there were tons of "space before tab" errors.
> And as I fixed them up, this made subsequent patches need rediffing
> since the contextual lines in patches after #5 needed the whitespace
> fixed up as well.
>
> I didn't push this back to you because this was already the 3rd round,
> but please show me some love and check this stuff out before
> submission. GIT gives you effective ways to verify the whitespace
> without even applying the patch.
>
> ~davem/bin/pcheck:
>
> #!/bin/sh
> set -x
> git apply --check --whitespace=error-all $1
Sorry, I will check that in the future :|
Many thanks for taking the time to fix that.
-- Daniel.
^ permalink raw reply
* Re: Linux IPv6 DAD not full conform to RFC 4862 ?
From: Neil Horman @ 2008-01-10 12:25 UTC (permalink / raw)
To: Vlad Yasevich
Cc: YOSHIFUJI Hideaki / 吉藤英明, kkeil,
netdev
In-Reply-To: <47853825.2030002@hp.com>
On Wed, Jan 09, 2008 at 04:09:57PM -0500, Vlad Yasevich wrote:
> Neil Horman wrote:
>> On Thu, Jan 10, 2008 at 01:38:57AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote:
>>> In article <20080109153656.GA16962@pingi.kke.suse.de> (at Wed, 9 Jan 2008 16:36:56 +0100), Karsten Keil <kkeil@suse.de> says:
>>>
>>>> So I think we should disable the interface now, if DAD fails on a
>>>> hardware based LLA.
>>> I don't want to do this, at least, unconditionally.
>>>
>>> Options (not exclusive):
>>>
>>> - we could have "dad_reaction" interface variable and
>>> > 1: disable interface
>>> = 1: disable IPv6
>>> < 0: ignore (as we do now)
>>>
>> I like the flexibility of this solution, but given that the only part of the RFC
>> that we're missing on at the moment is that we SHOULD disable the interface on
>> DAD failure for a link-local address, I would think this scheme would be good:
>>
>> < 0 : ignore, and del address from interface (current behavior) = 0 :
>> disable interface for dad failure for a link-local address > 0 : disable
>> interface for dad failure for any address
>> Regards
>> Neil
>>
>
> Just a friendly reminder that such a scheme should only be
> applied to autoconfigured addresses. A manually configured
> duplicated address should not bring down the whole interface.
>
I agree, but I think that case would be covered by the default option above
(sysctl < 0).
Neil
> -vlad
^ permalink raw reply
* EQL / doubts
From: Jeba Anandhan @ 2008-01-10 13:01 UTC (permalink / raw)
To: netdev
Hi All,
I have few questions about EQL driver
*) Why the tx_queue_len is set as 5?. For example if we bond 3 lines
and each has 1000 as tx_queue_len, will the bonding line(eql)
tx_queue_len be sum of these three tx_queue_len?. In this case, will the
bonding line(eql)tx_queue_len be 3000?
*)Question: Why list_add is used instead of list_add_tail?. For queue
implementation, list_add_tail would be required. Why do we implement of
slave queue in the way of stack implementation?.
File: linux/drivers/net/eql.c
Function: __eql_insert_slave(slave_queue_t *queue, slave_t *slave)
Code:
/* queue->lock must be held */
static int __eql_insert_slave(slave_queue_t *queue, slave_t *slave)
{
if (!eql_is_full(queue)) {
slave_t *duplicate_slave = NULL;
duplicate_slave = __eql_find_slave_dev(queue, slave->dev);
if (duplicate_slave != 0)
eql_kill_one_slave(queue, duplicate_slave);
list_add(&slave->list, &queue->all_slaves); // Why
list_add has been
used instead of list_add_tail?. I hope queue->all_slaves is queue
implementation.
*) Is it possible to improve the load balancing performance using
multiprocessor?. For example,if a server has two processors and N n/w
interfaces, is it possible to assign one processor for N/2 n/w
interface's tx and rx handling and other for N/2 n/w interface's tx/rx
handling
Thanks
Jeba
^ permalink raw reply
* Re: [PATCH 3/4] [XFRM]: Kill some bloat
From: Ilpo Järvinen @ 2008-01-10 13:53 UTC (permalink / raw)
To: andi
Cc: David Miller, Herbert Xu, Netdev, Arnaldo Carvalho de Melo,
paul.moore, latten
In-Reply-To: <Pine.LNX.4.64.0801081228010.12911@kivilampi-30.cs.helsinki.fi>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 4535 bytes --]
On Tue, 8 Jan 2008, Ilpo Järvinen wrote:
> On Mon, 7 Jan 2008, David Miller wrote:
>
> > From: Andi Kleen <andi@firstfloor.org>
> > Date: Tue, 8 Jan 2008 06:00:07 +0100
> >
> > > On Mon, Jan 07, 2008 at 07:37:00PM -0800, David Miller wrote:
> > > > The vast majority of them are one, two, and three liners.
> > >
> > > % awk ' { line++ } ; /^{/ { total++; start = line } ; /^}/ { len=line-start-3; if (len > 4) l++; if (len >= 10) k++; } ; END { print total, l, l/total, k, k/total }' < include/net/tcp.h
> > > 68 28 0.411765 20 0.294118
> > >
> > > 41% are over 4 lines, 29% are >= 10 lines.
> >
> > Take out the comments and whitespace lines, your script is
> > too simplistic.
In addition it triggered spuriously per struct/enum end brace :-) and
was using the last known function starting brace in there so no wonder
the numbers were that high... Counting with the corrected lines
(len=line-start-1) & spurious matches removed:
74 19 0.256757 7 0.0945946
Here are (finally) the measured bytes (couple of the functions are
missing because I had couple of bugs in the regexps and the #if trickery
at the inline resulted failed compiles):
12 funcs, 242+, 1697-, diff: -1455 tcp_set_state
13 funcs, 92+, 632-, diff: -540 tcp_is_cwnd_limited
12 funcs, 2836+, 3225-, diff: -389 tcp_current_ssthresh
5 funcs, 261+, 556-, diff: -295 tcp_prequeue
7 funcs, 2777+, 3049-, diff: -272 tcp_clear_retrans_hints_partial
11 funcs, 64+, 275-, diff: -211 tcp_win_from_space
6 funcs, 128+, 320-, diff: -192 tcp_prequeue_init
12 funcs, 45+, 209-, diff: -164 tcp_set_ca_state
7 funcs, 106+, 237-, diff: -131 tcp_fast_path_check
5 funcs, 167+, 291-, diff: -124 tcp_write_queue_purge
6 funcs, 43+, 160-, diff: -117 tcp_push_pending_frames
9 funcs, 55+, 159-, diff: -104 tcp_v4_check
6 funcs, 4+, 97-, diff: -93 tcp_packets_in_flight
7 funcs, 58+, 150-, diff: -92 tcp_fast_path_on
4 funcs, 4+, 91-, diff: -87 tcp_clear_options
6 funcs, 141+, 217-, diff: -76 tcp_openreq_init
8 funcs, 38+, 111-, diff: -73 tcp_unlink_write_queue
7 funcs, 32+, 103-, diff: -71 tcp_checksum_complete
7 funcs, 35+, 101-, diff: -66 __tcp_fast_path_on
5 funcs, 4+, 66-, diff: -62 tcp_receive_window
6 funcs, 67+, 128-, diff: -61 tcp_add_write_queue_tail
7 funcs, 30+, 86-, diff: -56 tcp_ca_event
6 funcs, 73+, 106-, diff: -33 tcp_paws_check
4 funcs, 4+, 36-, diff: -32 tcp_highest_sack_seq
6 funcs, 46+, 78-, diff: -32 tcp_fin_time
3 funcs, 4+, 35-, diff: -31 tcp_clear_all_retrans_hints
7 funcs, 30+, 51-, diff: -21 __tcp_add_write_queue_tail
3 funcs, 4+, 14-, diff: -10 tcp_enable_fack
4 funcs, 4+, 14-, diff: -10 keepalive_time_when
8 funcs, 66+, 73-, diff: -7 tcp_full_space
3 funcs, 4+, 5-, diff: -1 tcp_wnd_end
4 funcs, 97+, 97-, diff: +0 tcp_mib_init
3 funcs, 4+, 3-, diff: +1 tcp_skb_is_last
2 funcs, 4+, 2-, diff: +2 keepalive_intvl_when
2 funcs, 4+, 2-, diff: +2 tcp_is_fack
2 funcs, 4+, 2-, diff: +2 tcp_skb_mss
2 funcs, 4+, 2-, diff: +2 tcp_write_queue_empty
2 funcs, 4+, 2-, diff: +2 tcp_advance_highest_sack
2 funcs, 4+, 2-, diff: +2 tcp_advance_send_head
2 funcs, 4+, 2-, diff: +2 tcp_check_send_head
2 funcs, 4+, 2-, diff: +2 tcp_highest_sack_reset
2 funcs, 4+, 2-, diff: +2 tcp_init_send_head
2 funcs, 4+, 2-, diff: +2 tcp_sack_reset
6 funcs, 47+, 44-, diff: +3 tcp_space
5 funcs, 55+, 50-, diff: +5 tcp_too_many_orphans
3 funcs, 8+, 2-, diff: +6 tcp_minshall_update
3 funcs, 8+, 2-, diff: +6 tcp_update_wl
8 funcs, 25+, 14-, diff: +11 between
3 funcs, 14+, 2-, diff: +12 tcp_put_md5sig_pool
3 funcs, 14+, 2-, diff: +12 tcp_clear_xmit_timers
5 funcs, 30+, 17-, diff: +13 tcp_dec_pcount_approx_int
6 funcs, 33+, 20-, diff: +13 tcp_insert_write_queue_after
3 funcs, 17+, 2-, diff: +15 __tcp_checksum_complete
5 funcs, 17+, 2-, diff: +15 tcp_init_wl
4 funcs, 57+, 41-, diff: +16 tcp_dec_quickack_mode
4 funcs, 40+, 22-, diff: +18 __tcp_add_write_queue_head
5 funcs, 36+, 16-, diff: +20 tcp_highest_sack_combine
4 funcs, 40+, 18-, diff: +22 tcp_dec_pcount_approx
6 funcs, 29+, 5-, diff: +24 tcp_is_sack
4 funcs, 28+, 2-, diff: +26 tcp_is_reno
5 funcs, 50+, 24-, diff: +26 tcp_insert_write_queue_before
4 funcs, 83+, 56-, diff: +27 tcp_check_probe_timer
8 funcs, 69+, 14-, diff: +55 tcp_left_out
11 funcs, 2995+, 2893-, diff: +102 tcp_skb_pcount
30 funcs, 930+, 2-, diff: +928 before
--
i.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox