提交 5df285f6 编写于 作者: D David S. Miller

Merge branch 's390-qeth-next'

Ursula Braun says:

====================
s390: qeth patches

yesterday I came up with 13 qeth patches. Since you have not been
happy with the 13th patch, I want to make sure that at least the
remaining 12 qeth patches can be applied to net-next. Here is the
resend of them.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
......@@ -281,8 +281,6 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
#define QETH_HIGH_WATERMARK_PACK 5
#define QETH_WATERMARK_PACK_FUZZ 1
#define QETH_IP_HEADER_SIZE 40
/* large receive scatter gather copy break */
#define QETH_RX_SG_CB (PAGE_SIZE >> 1)
#define QETH_RX_PULL_LEN 256
......@@ -674,8 +672,6 @@ struct qeth_card_info {
int broadcast_capable;
int unique_id;
struct qeth_card_blkt blkt;
__u32 csum_mask;
__u32 tx_csum_mask;
enum qeth_ipa_promisc_modes promisc_mode;
__u32 diagass_support;
__u32 hwtrap;
......@@ -917,7 +913,6 @@ void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long);
int qeth_core_hardsetup_card(struct qeth_card *);
void qeth_print_status_message(struct qeth_card *);
int qeth_init_qdio_queues(struct qeth_card *);
int qeth_send_startlan(struct qeth_card *);
int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
int (*reply_cb)
(struct qeth_card *, struct qeth_reply *, unsigned long),
......
......@@ -2944,7 +2944,7 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
}
EXPORT_SYMBOL_GPL(qeth_send_ipa_cmd);
int qeth_send_startlan(struct qeth_card *card)
static int qeth_send_startlan(struct qeth_card *card)
{
int rc;
struct qeth_cmd_buffer *iob;
......@@ -2957,7 +2957,6 @@ int qeth_send_startlan(struct qeth_card *card)
rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
return rc;
}
EXPORT_SYMBOL_GPL(qeth_send_startlan);
static int qeth_default_setadapterparms_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data)
......@@ -5087,6 +5086,20 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
goto out;
}
rc = qeth_send_startlan(card);
if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
if (rc == IPA_RC_LAN_OFFLINE) {
dev_warn(&card->gdev->dev,
"The LAN is offline\n");
card->lan_online = 0;
} else {
rc = -ENODEV;
goto out;
}
} else
card->lan_online = 1;
card->options.ipa4.supported_funcs = 0;
card->options.ipa6.supported_funcs = 0;
card->options.adp.supported_funcs = 0;
......@@ -5098,14 +5111,14 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
rc = qeth_query_setadapterparms(card);
if (rc < 0) {
QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
QETH_DBF_TEXT_(SETUP, 2, "7err%d", rc);
goto out;
}
}
if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
rc = qeth_query_setdiagass(card);
if (rc < 0) {
QETH_DBF_TEXT_(SETUP, 2, "7err%d", rc);
QETH_DBF_TEXT_(SETUP, 2, "8err%d", rc);
goto out;
}
}
......@@ -5289,18 +5302,6 @@ int qeth_setassparms_cb(struct qeth_card *card,
if (cmd->hdr.prot_version == QETH_PROT_IPV6)
card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
}
if (cmd->data.setassparms.hdr.assist_no == IPA_INBOUND_CHECKSUM &&
cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
card->info.csum_mask = cmd->data.setassparms.data.flags_32bit;
QETH_CARD_TEXT_(card, 3, "csum:%d", card->info.csum_mask);
}
if (cmd->data.setassparms.hdr.assist_no == IPA_OUTBOUND_CHECKSUM &&
cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
card->info.tx_csum_mask =
cmd->data.setassparms.data.flags_32bit;
QETH_CARD_TEXT_(card, 3, "tcsu:%d", card->info.tx_csum_mask);
}
return 0;
}
EXPORT_SYMBOL_GPL(qeth_setassparms_cb);
......@@ -6060,23 +6061,96 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev,
}
EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_settings);
/* Callback to handle checksum offload command reply from OSA card.
* Verify that required features have been enabled on the card.
* Return error in hdr->return_code as this value is checked by caller.
*
* Always returns zero to indicate no further messages from the OSA card.
*/
static int qeth_ipa_checksum_run_cmd_cb(struct qeth_card *card,
struct qeth_reply *reply,
unsigned long data)
{
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
struct qeth_checksum_cmd *chksum_cb =
(struct qeth_checksum_cmd *)reply->param;
QETH_CARD_TEXT(card, 4, "chkdoccb");
if (cmd->hdr.return_code)
return 0;
memset(chksum_cb, 0, sizeof(*chksum_cb));
if (cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
chksum_cb->supported =
cmd->data.setassparms.data.chksum.supported;
QETH_CARD_TEXT_(card, 3, "strt:%x", chksum_cb->supported);
}
if (cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_ENABLE) {
chksum_cb->supported =
cmd->data.setassparms.data.chksum.supported;
chksum_cb->enabled =
cmd->data.setassparms.data.chksum.enabled;
QETH_CARD_TEXT_(card, 3, "supp:%x", chksum_cb->supported);
QETH_CARD_TEXT_(card, 3, "enab:%x", chksum_cb->enabled);
}
return 0;
}
/* Send command to OSA card and check results. */
static int qeth_ipa_checksum_run_cmd(struct qeth_card *card,
enum qeth_ipa_funcs ipa_func,
__u16 cmd_code, long data,
struct qeth_checksum_cmd *chksum_cb)
{
struct qeth_cmd_buffer *iob;
int rc = -ENOMEM;
QETH_CARD_TEXT(card, 4, "chkdocmd");
iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
sizeof(__u32), QETH_PROT_IPV4);
if (iob)
rc = qeth_send_setassparms(card, iob, sizeof(__u32), data,
qeth_ipa_checksum_run_cmd_cb,
chksum_cb);
return rc;
}
static int qeth_send_checksum_on(struct qeth_card *card, int cstype)
{
long rxtx_arg;
const __u32 required_features = QETH_IPA_CHECKSUM_IP_HDR |
QETH_IPA_CHECKSUM_UDP |
QETH_IPA_CHECKSUM_TCP;
struct qeth_checksum_cmd chksum_cb;
int rc;
rc = qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_START, 0);
rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_START, 0,
&chksum_cb);
if (!rc) {
if ((required_features & chksum_cb.supported) !=
required_features)
rc = -EIO;
else if (!(QETH_IPA_CHECKSUM_LP2LP & chksum_cb.supported) &&
cstype == IPA_INBOUND_CHECKSUM)
dev_warn(&card->gdev->dev,
"Hardware checksumming is performed only if %s and its peer use different OSA Express 3 ports\n",
QETH_CARD_IFNAME(card));
}
if (rc) {
qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_STOP, 0);
dev_warn(&card->gdev->dev,
"Starting HW checksumming for %s failed, using SW checksumming\n",
QETH_CARD_IFNAME(card));
return rc;
}
rxtx_arg = (cstype == IPA_OUTBOUND_CHECKSUM) ? card->info.tx_csum_mask
: card->info.csum_mask;
rc = qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_ENABLE,
rxtx_arg);
rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_ENABLE,
chksum_cb.supported, &chksum_cb);
if (!rc) {
if ((required_features & chksum_cb.enabled) !=
required_features)
rc = -EIO;
}
if (rc) {
qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_STOP, 0);
dev_warn(&card->gdev->dev,
"Enabling HW checksumming for %s failed, using SW checksumming\n",
QETH_CARD_IFNAME(card));
......@@ -6090,19 +6164,10 @@ static int qeth_send_checksum_on(struct qeth_card *card, int cstype)
static int qeth_set_ipa_csum(struct qeth_card *card, int on, int cstype)
{
int rc;
if (on) {
rc = qeth_send_checksum_on(card, cstype);
if (rc)
return -EIO;
} else {
rc = qeth_send_simple_setassparms(card, cstype,
IPA_CMD_ASS_STOP, 0);
if (rc)
return -EIO;
}
return 0;
int rc = (on) ? qeth_send_checksum_on(card, cstype)
: qeth_send_simple_setassparms(card, cstype,
IPA_CMD_ASS_STOP, 0);
return rc ? -EIO : 0;
}
static int qeth_set_ipa_tso(struct qeth_card *card, int on)
......
......@@ -352,11 +352,28 @@ struct qeth_arp_query_info {
char *udata;
};
/* IPA set assist segmentation bit definitions for receive and
* transmit checksum offloading.
*/
enum qeth_ipa_checksum_bits {
QETH_IPA_CHECKSUM_IP_HDR = 0x0002,
QETH_IPA_CHECKSUM_UDP = 0x0008,
QETH_IPA_CHECKSUM_TCP = 0x0010,
QETH_IPA_CHECKSUM_LP2LP = 0x0020
};
/* IPA Assist checksum offload reply layout. */
struct qeth_checksum_cmd {
__u32 supported;
__u32 enabled;
} __packed;
/* SETASSPARMS IPA Command: */
struct qeth_ipacmd_setassparms {
struct qeth_ipacmd_setassparms_hdr hdr;
union {
__u32 flags_32bit;
struct qeth_checksum_cmd chksum;
struct qeth_arp_cache_entry add_arp_entry;
struct qeth_arp_query_data query_arp;
__u8 ip[16];
......
......@@ -27,9 +27,6 @@
static int qeth_l2_set_offline(struct ccwgroup_device *);
static int qeth_l2_stop(struct net_device *);
static int qeth_l2_send_delmac(struct qeth_card *, __u8 *);
static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *,
enum qeth_ipa_cmds);
static void qeth_l2_set_rx_mode(struct net_device *);
static int qeth_l2_recover(void *);
static void qeth_bridgeport_query_support(struct qeth_card *card);
......@@ -165,13 +162,70 @@ static int qeth_setdel_makerc(struct qeth_card *card, int retcode)
return rc;
}
static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
enum qeth_ipa_cmds ipacmd)
{
struct qeth_ipa_cmd *cmd;
struct qeth_cmd_buffer *iob;
QETH_CARD_TEXT(card, 2, "L2sdmac");
iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
if (!iob)
return -ENOMEM;
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
return qeth_setdel_makerc(card, qeth_send_ipa_cmd(card, iob,
NULL, NULL));
}
static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
{
int rc;
QETH_CARD_TEXT(card, 2, "L2Setmac");
rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC);
if (rc == 0) {
card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN);
dev_info(&card->gdev->dev,
"MAC address %pM successfully registered on device %s\n",
card->dev->dev_addr, card->dev->name);
} else {
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
switch (rc) {
case -EEXIST:
dev_warn(&card->gdev->dev,
"MAC address %pM already exists\n", mac);
break;
case -EPERM:
dev_warn(&card->gdev->dev,
"MAC address %pM is not authorized\n", mac);
break;
}
}
return rc;
}
static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)
{
int rc;
QETH_CARD_TEXT(card, 2, "L2Delmac");
if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
return 0;
rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC);
if (rc == 0)
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
return rc;
}
static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac)
{
int rc;
QETH_CARD_TEXT(card, 2, "L2Sgmac");
rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
IPA_CMD_SETGMAC));
rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC);
if (rc == -EEXIST)
QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s\n",
mac, QETH_CARD_IFNAME(card));
......@@ -186,8 +240,7 @@ static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
int rc;
QETH_CARD_TEXT(card, 2, "L2Dgmac");
rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
IPA_CMD_DELGMAC));
rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC);
if (rc)
QETH_DBF_MESSAGE(2,
"Could not delete group MAC %pM on %s: %d\n",
......@@ -195,28 +248,27 @@ static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
return rc;
}
static inline u32 qeth_l2_mac_hash(const u8 *addr)
static int qeth_l2_write_mac(struct qeth_card *card, struct qeth_mac *mac)
{
return get_unaligned((u32 *)(&addr[2]));
if (mac->is_uc) {
return qeth_l2_send_setdelmac(card, mac->mac_addr,
IPA_CMD_SETVMAC);
} else {
return qeth_l2_send_setgroupmac(card, mac->mac_addr);
}
}
static int qeth_l2_write_mac(struct qeth_card *card, struct qeth_mac *mac)
static int qeth_l2_remove_mac(struct qeth_card *card, struct qeth_mac *mac)
{
int rc;
if (mac->is_uc) {
rc = qeth_setdel_makerc(card,
qeth_l2_send_setdelmac(card, mac->mac_addr,
IPA_CMD_SETVMAC));
return qeth_l2_send_setdelmac(card, mac->mac_addr,
IPA_CMD_DELVMAC);
} else {
rc = qeth_setdel_makerc(card,
qeth_l2_send_setgroupmac(card, mac->mac_addr));
return qeth_l2_send_delgroupmac(card, mac->mac_addr);
}
return rc;
}
static void qeth_l2_del_all_macs(struct qeth_card *card, int del)
static void qeth_l2_del_all_macs(struct qeth_card *card)
{
struct qeth_mac *mac;
struct hlist_node *tmp;
......@@ -224,19 +276,17 @@ static void qeth_l2_del_all_macs(struct qeth_card *card, int del)
spin_lock_bh(&card->mclock);
hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
if (del) {
if (mac->is_uc)
qeth_l2_send_setdelmac(card, mac->mac_addr,
IPA_CMD_DELVMAC);
else
qeth_l2_send_delgroupmac(card, mac->mac_addr);
}
hash_del(&mac->hnode);
kfree(mac);
}
spin_unlock_bh(&card->mclock);
}
static inline u32 qeth_l2_mac_hash(const u8 *addr)
{
return get_unaligned((u32 *)(&addr[2]));
}
static inline int qeth_l2_get_cast_type(struct qeth_card *card,
struct sk_buff *skb)
{
......@@ -425,7 +475,7 @@ static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
card->state = CARD_STATE_SOFTSETUP;
}
if (card->state == CARD_STATE_SOFTSETUP) {
qeth_l2_del_all_macs(card, 0);
qeth_l2_del_all_macs(card);
qeth_clear_ipacmd_list(card);
card->state = CARD_STATE_HARDSETUP;
}
......@@ -577,65 +627,6 @@ static int qeth_l2_poll(struct napi_struct *napi, int budget)
return work_done;
}
static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
enum qeth_ipa_cmds ipacmd)
{
struct qeth_ipa_cmd *cmd;
struct qeth_cmd_buffer *iob;
QETH_CARD_TEXT(card, 2, "L2sdmac");
iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
if (!iob)
return -ENOMEM;
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
return qeth_send_ipa_cmd(card, iob, NULL, NULL);
}
static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
{
int rc;
QETH_CARD_TEXT(card, 2, "L2Setmac");
rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
IPA_CMD_SETVMAC));
if (rc == 0) {
card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN);
dev_info(&card->gdev->dev,
"MAC address %pM successfully registered on device %s\n",
card->dev->dev_addr, card->dev->name);
} else {
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
switch (rc) {
case -EEXIST:
dev_warn(&card->gdev->dev,
"MAC address %pM already exists\n", mac);
break;
case -EPERM:
dev_warn(&card->gdev->dev,
"MAC address %pM is not authorized\n", mac);
break;
}
}
return rc;
}
static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)
{
int rc;
QETH_CARD_TEXT(card, 2, "L2Delmac");
if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
return 0;
rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
IPA_CMD_DELVMAC));
if (rc == 0)
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
return rc;
}
static int qeth_l2_request_initial_mac(struct qeth_card *card)
{
int rc = 0;
......@@ -794,14 +785,7 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
if (mac->disp_flag == QETH_DISP_ADDR_DELETE) {
if (!mac->is_uc)
rc = qeth_l2_send_delgroupmac(card,
mac->mac_addr);
else {
rc = qeth_l2_send_setdelmac(card, mac->mac_addr,
IPA_CMD_DELVMAC);
}
qeth_l2_remove_mac(card, mac);
hash_del(&mac->hnode);
kfree(mac);
......@@ -1193,21 +1177,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
/* softsetup */
QETH_DBF_TEXT(SETUP, 2, "softsetp");
rc = qeth_send_startlan(card);
if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
if (rc == 0xe080) {
dev_warn(&card->gdev->dev,
"The LAN is offline\n");
card->lan_online = 0;
goto contin;
}
rc = -ENODEV;
goto out_remove;
} else
card->lan_online = 1;
contin:
if ((card->info.type == QETH_CARD_TYPE_OSD) ||
(card->info.type == QETH_CARD_TYPE_OSX)) {
rc = qeth_l2_start_ipassists(card);
......
......@@ -3227,21 +3227,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
/* softsetup */
QETH_DBF_TEXT(SETUP, 2, "softsetp");
rc = qeth_send_startlan(card);
if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
if (rc == 0xe080) {
dev_warn(&card->gdev->dev,
"The LAN is offline\n");
card->lan_online = 0;
goto contin;
}
rc = -ENODEV;
goto out_remove;
} else
card->lan_online = 1;
contin:
rc = qeth_l3_setadapter_parms(card);
if (rc)
QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc);
......
......@@ -250,9 +250,6 @@ static ssize_t qeth_l3_dev_hsuid_show(struct device *dev,
if (card->info.type != QETH_CARD_TYPE_IQD)
return -EPERM;
if (card->state == CARD_STATE_DOWN)
return -EPERM;
memcpy(tmp_hsuid, card->options.hsuid, sizeof(tmp_hsuid));
EBCASC(tmp_hsuid, 8);
return sprintf(buf, "%s\n", tmp_hsuid);
......@@ -692,15 +689,15 @@ static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
enum qeth_prot_versions proto)
{
struct qeth_ipaddr *ipaddr;
struct hlist_node *tmp;
char addr_str[40];
int str_len = 0;
int entry_len; /* length of 1 entry string, differs between v4 and v6 */
int i = 0;
int i;
entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
entry_len += 2; /* \n + terminator */
spin_lock_bh(&card->ip_lock);
hash_for_each_safe(card->ip_htable, i, tmp, ipaddr, hnode) {
hash_for_each(card->ip_htable, i, ipaddr, hnode) {
if (ipaddr->proto != proto)
continue;
if (ipaddr->type != QETH_IP_TYPE_VIPA)
......@@ -708,16 +705,17 @@ static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
/* String must not be longer than PAGE_SIZE. So we check if
* string length gets near PAGE_SIZE. Then we can savely display
* the next IPv6 address (worst case, compared to IPv4) */
if ((PAGE_SIZE - i) <= entry_len)
if ((PAGE_SIZE - str_len) <= entry_len)
break;
qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
addr_str);
i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "%s\n",
addr_str);
}
spin_unlock_bh(&card->ip_lock);
i += snprintf(buf + i, PAGE_SIZE - i, "\n");
str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "\n");
return i;
return str_len;
}
static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
......@@ -854,15 +852,15 @@ static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
enum qeth_prot_versions proto)
{
struct qeth_ipaddr *ipaddr;
struct hlist_node *tmp;
char addr_str[40];
int str_len = 0;
int entry_len; /* length of 1 entry string, differs between v4 and v6 */
int i = 0;
int i;
entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
entry_len += 2; /* \n + terminator */
spin_lock_bh(&card->ip_lock);
hash_for_each_safe(card->ip_htable, i, tmp, ipaddr, hnode) {
hash_for_each(card->ip_htable, i, ipaddr, hnode) {
if (ipaddr->proto != proto)
continue;
if (ipaddr->type != QETH_IP_TYPE_RXIP)
......@@ -870,16 +868,17 @@ static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
/* String must not be longer than PAGE_SIZE. So we check if
* string length gets near PAGE_SIZE. Then we can savely display
* the next IPv6 address (worst case, compared to IPv4) */
if ((PAGE_SIZE - i) <= entry_len)
if ((PAGE_SIZE - str_len) <= entry_len)
break;
qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
addr_str);
i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "%s\n",
addr_str);
}
spin_unlock_bh(&card->ip_lock);
i += snprintf(buf + i, PAGE_SIZE - i, "\n");
str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "\n");
return i;
return str_len;
}
static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册