mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 02:34:23 +08:00
Merge branch 's390-net-updates-part-2'
Julian Wiedmann says: ==================== s390/net updates, part 2 (v2) thanks for the feedback. Here's an updated patchset that honours the reverse christmas tree and drops the __packed attribute. Please apply. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
8abd5599a5
@ -8,6 +8,7 @@
|
||||
#ifndef _ASM_S390_DIAG_H
|
||||
#define _ASM_S390_DIAG_H
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
enum diag_stat_enum {
|
||||
@ -24,6 +25,7 @@ enum diag_stat_enum {
|
||||
DIAG_STAT_X224,
|
||||
DIAG_STAT_X250,
|
||||
DIAG_STAT_X258,
|
||||
DIAG_STAT_X26C,
|
||||
DIAG_STAT_X288,
|
||||
DIAG_STAT_X2C4,
|
||||
DIAG_STAT_X2FC,
|
||||
@ -225,6 +227,30 @@ struct diag204_x_phys_block {
|
||||
struct diag204_x_phys_cpu cpus[];
|
||||
} __packed;
|
||||
|
||||
enum diag26c_sc {
|
||||
DIAG26C_MAC_SERVICES = 0x00000030
|
||||
};
|
||||
|
||||
enum diag26c_version {
|
||||
DIAG26C_VERSION2 = 0x00000002 /* z/VM 5.4.0 */
|
||||
};
|
||||
|
||||
#define DIAG26C_GET_MAC 0x0000
|
||||
struct diag26c_mac_req {
|
||||
u32 resp_buf_len;
|
||||
u32 resp_version;
|
||||
u16 op_code;
|
||||
u16 devno;
|
||||
u8 res[4];
|
||||
};
|
||||
|
||||
struct diag26c_mac_resp {
|
||||
u32 version;
|
||||
u8 mac[ETH_ALEN];
|
||||
u8 res[2];
|
||||
} __aligned(8);
|
||||
|
||||
int diag204(unsigned long subcode, unsigned long size, void *addr);
|
||||
int diag224(void *ptr);
|
||||
int diag26c(void *req, void *resp, enum diag26c_sc subcode);
|
||||
#endif /* _ASM_S390_DIAG_H */
|
||||
|
@ -38,6 +38,7 @@ static const struct diag_desc diag_map[NR_DIAG_STAT] = {
|
||||
[DIAG_STAT_X224] = { .code = 0x224, .name = "EBCDIC-Name Table" },
|
||||
[DIAG_STAT_X250] = { .code = 0x250, .name = "Block I/O" },
|
||||
[DIAG_STAT_X258] = { .code = 0x258, .name = "Page-Reference Services" },
|
||||
[DIAG_STAT_X26C] = { .code = 0x26c, .name = "Certain System Information" },
|
||||
[DIAG_STAT_X288] = { .code = 0x288, .name = "Time Bomb" },
|
||||
[DIAG_STAT_X2C4] = { .code = 0x2c4, .name = "FTP Services" },
|
||||
[DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" },
|
||||
@ -236,3 +237,31 @@ int diag224(void *ptr)
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(diag224);
|
||||
|
||||
/*
|
||||
* Diagnose 26C: Access Certain System Information
|
||||
*/
|
||||
static inline int __diag26c(void *req, void *resp, enum diag26c_sc subcode)
|
||||
{
|
||||
register unsigned long _req asm("2") = (addr_t) req;
|
||||
register unsigned long _resp asm("3") = (addr_t) resp;
|
||||
register unsigned long _subcode asm("4") = subcode;
|
||||
register unsigned long _rc asm("5") = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" sam31\n"
|
||||
" diag %[rx],%[ry],0x26c\n"
|
||||
"0: sam64\n"
|
||||
EX_TABLE(0b,0b)
|
||||
: "+d" (_rc)
|
||||
: [rx] "d" (_req), "d" (_resp), [ry] "d" (_subcode)
|
||||
: "cc", "memory");
|
||||
return _rc;
|
||||
}
|
||||
|
||||
int diag26c(void *req, void *resp, enum diag26c_sc subcode)
|
||||
{
|
||||
diag_stat_inc(DIAG_STAT_X26C);
|
||||
return __diag26c(req, resp, subcode);
|
||||
}
|
||||
EXPORT_SYMBOL(diag26c);
|
||||
|
@ -986,6 +986,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *,
|
||||
int qeth_set_features(struct net_device *, netdev_features_t);
|
||||
int qeth_recover_features(struct net_device *);
|
||||
netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);
|
||||
int qeth_vm_request_mac(struct qeth_card *card);
|
||||
|
||||
/* exports for OSN */
|
||||
int qeth_osn_assist(struct net_device *, void *, int);
|
||||
|
@ -27,6 +27,9 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/sysinfo.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/diag.h>
|
||||
#include <asm/cio.h>
|
||||
#include <asm/ccwdev.h>
|
||||
|
||||
#include "qeth_core.h"
|
||||
|
||||
@ -4103,7 +4106,8 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
|
||||
flush_count);
|
||||
atomic_set(&queue->state,
|
||||
QETH_OUT_Q_UNLOCKED);
|
||||
return -EBUSY;
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4122,19 +4126,21 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
|
||||
* In that case we will enter this loop
|
||||
*/
|
||||
while (atomic_dec_return(&queue->state)) {
|
||||
flush_count = 0;
|
||||
start_index = queue->next_buf_to_fill;
|
||||
/* check if we can go back to non-packing state */
|
||||
flush_count += qeth_switch_to_nonpacking_if_needed(queue);
|
||||
tmp = qeth_switch_to_nonpacking_if_needed(queue);
|
||||
/*
|
||||
* check if we need to flush a packing buffer to get a pci
|
||||
* flag out on the queue
|
||||
*/
|
||||
if (!flush_count && !atomic_read(&queue->set_pci_flags_count))
|
||||
flush_count += qeth_prep_flush_pack_buffer(queue);
|
||||
if (flush_count)
|
||||
qeth_flush_buffers(queue, start_index, flush_count);
|
||||
if (!tmp && !atomic_read(&queue->set_pci_flags_count))
|
||||
tmp = qeth_prep_flush_pack_buffer(queue);
|
||||
if (tmp) {
|
||||
qeth_flush_buffers(queue, start_index, tmp);
|
||||
flush_count += tmp;
|
||||
}
|
||||
}
|
||||
out:
|
||||
/* at this point the queue is UNLOCKED again */
|
||||
if (queue->card->options.performance_stats && do_pack)
|
||||
queue->card->perf_stats.bufs_sent_pack += flush_count;
|
||||
@ -4770,6 +4776,64 @@ static int qeth_query_card_info(struct qeth_card *card,
|
||||
(void *)carrier_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* qeth_vm_request_mac() - Request a hypervisor-managed MAC address
|
||||
* @card: pointer to a qeth_card
|
||||
*
|
||||
* Returns
|
||||
* 0, if a MAC address has been set for the card's netdevice
|
||||
* a return code, for various error conditions
|
||||
*/
|
||||
int qeth_vm_request_mac(struct qeth_card *card)
|
||||
{
|
||||
struct diag26c_mac_resp *response;
|
||||
struct diag26c_mac_req *request;
|
||||
struct ccw_dev_id id;
|
||||
int rc;
|
||||
|
||||
QETH_DBF_TEXT(SETUP, 2, "vmreqmac");
|
||||
|
||||
if (!card->dev)
|
||||
return -ENODEV;
|
||||
|
||||
request = kzalloc(sizeof(*request), GFP_KERNEL | GFP_DMA);
|
||||
response = kzalloc(sizeof(*response), GFP_KERNEL | GFP_DMA);
|
||||
if (!request || !response) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ccw_device_get_id(CARD_DDEV(card), &id);
|
||||
request->resp_buf_len = sizeof(*response);
|
||||
request->resp_version = DIAG26C_VERSION2;
|
||||
request->op_code = DIAG26C_GET_MAC;
|
||||
request->devno = id.devno;
|
||||
|
||||
rc = diag26c(request, response, DIAG26C_MAC_SERVICES);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
if (request->resp_buf_len < sizeof(*response) ||
|
||||
response->version != request->resp_version) {
|
||||
rc = -EIO;
|
||||
QETH_DBF_TEXT(SETUP, 2, "badresp");
|
||||
QETH_DBF_HEX(SETUP, 2, &request->resp_buf_len,
|
||||
sizeof(request->resp_buf_len));
|
||||
} else if (!is_valid_ether_addr(response->mac)) {
|
||||
rc = -EINVAL;
|
||||
QETH_DBF_TEXT(SETUP, 2, "badmac");
|
||||
QETH_DBF_HEX(SETUP, 2, response->mac, ETH_ALEN);
|
||||
} else {
|
||||
ether_addr_copy(card->dev->dev_addr, response->mac);
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(response);
|
||||
kfree(request);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_vm_request_mac);
|
||||
|
||||
static inline int qeth_get_qdio_q_format(struct qeth_card *card)
|
||||
{
|
||||
if (card->info.type == QETH_CARD_TYPE_IQD)
|
||||
|
@ -170,12 +170,18 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
|
||||
{IPA_RC_TRACE_ALREADY_ACTIVE, "trace already active"},
|
||||
{IPA_RC_INVALID_FORMAT, "invalid format or length"},
|
||||
{IPA_RC_DUP_IPV6_REMOTE, "ipv6 address already registered remote"},
|
||||
{IPA_RC_SBP_IQD_NOT_CONFIGURED, "Not configured for bridgeport"},
|
||||
{IPA_RC_DUP_IPV6_HOME, "ipv6 address already registered"},
|
||||
{IPA_RC_UNREGISTERED_ADDR, "Address not registered"},
|
||||
{IPA_RC_NO_ID_AVAILABLE, "No identifiers available"},
|
||||
{IPA_RC_ID_NOT_FOUND, "Identifier not found"},
|
||||
{IPA_RC_SBP_IQD_ANO_DEV_PRIMARY, "Primary bridgeport exists already"},
|
||||
{IPA_RC_SBP_IQD_CURRENT_SECOND, "Bridgeport is currently secondary"},
|
||||
{IPA_RC_SBP_IQD_LIMIT_SECOND, "Limit of secondary bridgeports reached"},
|
||||
{IPA_RC_INVALID_IP_VERSION, "IP version incorrect"},
|
||||
{IPA_RC_SBP_IQD_CURRENT_PRIMARY, "Bridgeport is currently primary"},
|
||||
{IPA_RC_LAN_FRAME_MISMATCH, "LAN and frame mismatch"},
|
||||
{IPA_RC_SBP_IQD_NO_QDIO_QUEUES, "QDIO queues not established"},
|
||||
{IPA_RC_L2_UNSUPPORTED_CMD, "Unsupported layer 2 command"},
|
||||
{IPA_RC_L2_DUP_MAC, "Duplicate MAC address"},
|
||||
{IPA_RC_L2_ADDR_TABLE_FULL, "Layer2 address table full"},
|
||||
@ -187,6 +193,14 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
|
||||
{IPA_RC_L2_INVALID_VLAN_ID, "L2 invalid vlan id"},
|
||||
{IPA_RC_L2_DUP_VLAN_ID, "L2 duplicate vlan id"},
|
||||
{IPA_RC_L2_VLAN_ID_NOT_FOUND, "L2 vlan id not found"},
|
||||
{IPA_RC_SBP_OSA_NOT_CONFIGURED, "Not configured for bridgeport"},
|
||||
{IPA_RC_SBP_OSA_OS_MISMATCH, "OS mismatch"},
|
||||
{IPA_RC_SBP_OSA_ANO_DEV_PRIMARY, "Primary bridgeport exists already"},
|
||||
{IPA_RC_SBP_OSA_CURRENT_SECOND, "Bridgeport is currently secondary"},
|
||||
{IPA_RC_SBP_OSA_LIMIT_SECOND, "Limit of secondary bridgeports reached"},
|
||||
{IPA_RC_SBP_OSA_NOT_AUTHD_BY_ZMAN, "Not authorized by zManager"},
|
||||
{IPA_RC_SBP_OSA_CURRENT_PRIMARY, "Bridgeport is currently primary"},
|
||||
{IPA_RC_SBP_OSA_NO_QDIO_QUEUES, "QDIO queues not established"},
|
||||
{IPA_RC_DATA_MISMATCH, "Data field mismatch (v4/v6 mixed)"},
|
||||
{IPA_RC_INVALID_MTU_SIZE, "Invalid MTU size"},
|
||||
{IPA_RC_INVALID_LANTYPE, "Invalid LAN type"},
|
||||
|
@ -142,12 +142,18 @@ enum qeth_ipa_return_codes {
|
||||
IPA_RC_TRACE_ALREADY_ACTIVE = 0x0005,
|
||||
IPA_RC_INVALID_FORMAT = 0x0006,
|
||||
IPA_RC_DUP_IPV6_REMOTE = 0x0008,
|
||||
IPA_RC_SBP_IQD_NOT_CONFIGURED = 0x000C,
|
||||
IPA_RC_DUP_IPV6_HOME = 0x0010,
|
||||
IPA_RC_UNREGISTERED_ADDR = 0x0011,
|
||||
IPA_RC_NO_ID_AVAILABLE = 0x0012,
|
||||
IPA_RC_ID_NOT_FOUND = 0x0013,
|
||||
IPA_RC_SBP_IQD_ANO_DEV_PRIMARY = 0x0014,
|
||||
IPA_RC_SBP_IQD_CURRENT_SECOND = 0x0018,
|
||||
IPA_RC_SBP_IQD_LIMIT_SECOND = 0x001C,
|
||||
IPA_RC_INVALID_IP_VERSION = 0x0020,
|
||||
IPA_RC_SBP_IQD_CURRENT_PRIMARY = 0x0024,
|
||||
IPA_RC_LAN_FRAME_MISMATCH = 0x0040,
|
||||
IPA_RC_SBP_IQD_NO_QDIO_QUEUES = 0x00EB,
|
||||
IPA_RC_L2_UNSUPPORTED_CMD = 0x2003,
|
||||
IPA_RC_L2_DUP_MAC = 0x2005,
|
||||
IPA_RC_L2_ADDR_TABLE_FULL = 0x2006,
|
||||
@ -159,6 +165,14 @@ enum qeth_ipa_return_codes {
|
||||
IPA_RC_L2_INVALID_VLAN_ID = 0x2015,
|
||||
IPA_RC_L2_DUP_VLAN_ID = 0x2016,
|
||||
IPA_RC_L2_VLAN_ID_NOT_FOUND = 0x2017,
|
||||
IPA_RC_SBP_OSA_NOT_CONFIGURED = 0x2B0C,
|
||||
IPA_RC_SBP_OSA_OS_MISMATCH = 0x2B10,
|
||||
IPA_RC_SBP_OSA_ANO_DEV_PRIMARY = 0x2B14,
|
||||
IPA_RC_SBP_OSA_CURRENT_SECOND = 0x2B18,
|
||||
IPA_RC_SBP_OSA_LIMIT_SECOND = 0x2B1C,
|
||||
IPA_RC_SBP_OSA_NOT_AUTHD_BY_ZMAN = 0x2B20,
|
||||
IPA_RC_SBP_OSA_CURRENT_PRIMARY = 0x2B24,
|
||||
IPA_RC_SBP_OSA_NO_QDIO_QUEUES = 0x2BEB,
|
||||
IPA_RC_DATA_MISMATCH = 0xe001,
|
||||
IPA_RC_INVALID_MTU_SIZE = 0xe002,
|
||||
IPA_RC_INVALID_LANTYPE = 0xe003,
|
||||
@ -187,6 +201,10 @@ enum qeth_ipa_return_codes {
|
||||
#define IPA_RC_INVALID_SUBCMD IPA_RC_IP_TABLE_FULL
|
||||
#define IPA_RC_HARDWARE_AUTH_ERROR IPA_RC_UNKNOWN_ERROR
|
||||
|
||||
/* for SETBRIDGEPORT (double occupancies) */
|
||||
#define IPA_RC_SBP_IQD_OS_MISMATCH IPA_RC_DUP_IPV6_HOME
|
||||
#define IPA_RC_SBP_IQD_NOT_AUTHD_BY_ZMAN IPA_RC_INVALID_IP_VERSION
|
||||
|
||||
/* IPA function flags; each flag marks availability of respective function */
|
||||
enum qeth_ipa_funcs {
|
||||
IPA_ARP_PROCESSING = 0x00000001L,
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/hash.h>
|
||||
#include <linux/hashtable.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/setup.h>
|
||||
#include "qeth_core.h"
|
||||
#include "qeth_l2.h"
|
||||
|
||||
@ -505,9 +506,19 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card)
|
||||
int rc = 0;
|
||||
char vendor_pre[] = {0x02, 0x00, 0x00};
|
||||
|
||||
QETH_DBF_TEXT(SETUP, 2, "doL2init");
|
||||
QETH_DBF_TEXT(SETUP, 2, "l2reqmac");
|
||||
QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card));
|
||||
|
||||
if (MACHINE_IS_VM) {
|
||||
rc = qeth_vm_request_mac(card);
|
||||
if (!rc)
|
||||
goto out;
|
||||
QETH_DBF_MESSAGE(2, "z/VM MAC Service failed on device %s: x%x\n",
|
||||
CARD_BUS_ID(card), rc);
|
||||
QETH_DBF_TEXT_(SETUP, 2, "err%04x", rc);
|
||||
/* fall back to alternative mechanism: */
|
||||
}
|
||||
|
||||
if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
|
||||
rc = qeth_query_setadapterparms(card);
|
||||
if (rc) {
|
||||
@ -528,11 +539,12 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card)
|
||||
QETH_DBF_TEXT_(SETUP, 2, "1err%04x", rc);
|
||||
return rc;
|
||||
}
|
||||
QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, OSA_ADDR_LEN);
|
||||
} else {
|
||||
eth_random_addr(card->dev->dev_addr);
|
||||
memcpy(card->dev->dev_addr, vendor_pre, 3);
|
||||
}
|
||||
out:
|
||||
QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, card->dev->addr_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1650,27 +1662,27 @@ static int qeth_bridgeport_makerc(struct qeth_card *card,
|
||||
if ((is_iqd && (cbctl->ipa_rc == IPA_RC_SUCCESS)) ||
|
||||
(!is_iqd && (cbctl->ipa_rc == cbctl->cmd_rc)))
|
||||
switch (cbctl->cmd_rc) {
|
||||
case 0x0000:
|
||||
case IPA_RC_SUCCESS:
|
||||
rc = 0;
|
||||
break;
|
||||
case 0x2B04:
|
||||
case 0x0004:
|
||||
case IPA_RC_L2_UNSUPPORTED_CMD:
|
||||
case IPA_RC_UNSUPPORTED_COMMAND:
|
||||
rc = -EOPNOTSUPP;
|
||||
break;
|
||||
case 0x2B0C:
|
||||
case 0x000C: /* Not configured as bridge Port */
|
||||
case IPA_RC_SBP_OSA_NOT_CONFIGURED:
|
||||
case IPA_RC_SBP_IQD_NOT_CONFIGURED:
|
||||
rc = -ENODEV; /* maybe not the best code here? */
|
||||
dev_err(&card->gdev->dev,
|
||||
"The device is not configured as a Bridge Port\n");
|
||||
break;
|
||||
case 0x2B10:
|
||||
case 0x0010: /* OS mismatch */
|
||||
case IPA_RC_SBP_OSA_OS_MISMATCH:
|
||||
case IPA_RC_SBP_IQD_OS_MISMATCH:
|
||||
rc = -EPERM;
|
||||
dev_err(&card->gdev->dev,
|
||||
"A Bridge Port is already configured by a different operating system\n");
|
||||
break;
|
||||
case 0x2B14:
|
||||
case 0x0014: /* Another device is Primary */
|
||||
case IPA_RC_SBP_OSA_ANO_DEV_PRIMARY:
|
||||
case IPA_RC_SBP_IQD_ANO_DEV_PRIMARY:
|
||||
switch (setcmd) {
|
||||
case IPA_SBP_SET_PRIMARY_BRIDGE_PORT:
|
||||
rc = -EEXIST;
|
||||
@ -1686,26 +1698,26 @@ static int qeth_bridgeport_makerc(struct qeth_card *card,
|
||||
rc = -EIO;
|
||||
}
|
||||
break;
|
||||
case 0x2B18:
|
||||
case 0x0018: /* This device is currently Secondary */
|
||||
case IPA_RC_SBP_OSA_CURRENT_SECOND:
|
||||
case IPA_RC_SBP_IQD_CURRENT_SECOND:
|
||||
rc = -EBUSY;
|
||||
dev_err(&card->gdev->dev,
|
||||
"The device is already a secondary Bridge Port\n");
|
||||
break;
|
||||
case 0x2B1C:
|
||||
case 0x001C: /* Limit for Secondary devices reached */
|
||||
case IPA_RC_SBP_OSA_LIMIT_SECOND:
|
||||
case IPA_RC_SBP_IQD_LIMIT_SECOND:
|
||||
rc = -EEXIST;
|
||||
dev_err(&card->gdev->dev,
|
||||
"The LAN cannot have more secondary Bridge Ports\n");
|
||||
break;
|
||||
case 0x2B24:
|
||||
case 0x0024: /* This device is currently Primary */
|
||||
case IPA_RC_SBP_OSA_CURRENT_PRIMARY:
|
||||
case IPA_RC_SBP_IQD_CURRENT_PRIMARY:
|
||||
rc = -EBUSY;
|
||||
dev_err(&card->gdev->dev,
|
||||
"The device is already a primary Bridge Port\n");
|
||||
break;
|
||||
case 0x2B20:
|
||||
case 0x0020: /* Not authorized by zManager */
|
||||
case IPA_RC_SBP_OSA_NOT_AUTHD_BY_ZMAN:
|
||||
case IPA_RC_SBP_IQD_NOT_AUTHD_BY_ZMAN:
|
||||
rc = -EACCES;
|
||||
dev_err(&card->gdev->dev,
|
||||
"The device is not authorized to be a Bridge Port\n");
|
||||
|
Loading…
Reference in New Issue
Block a user