|
@@ -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"
|
|
|
|
|
@@ -4773,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)
|