s390/cio: Add new Operation Code OC3 to PNSO
Add support for operation code 3 (OC3) of the Perform-Network-Subchannel-Operations (PNSO) function of the Channel-Subsystem-Call (CHSC) instruction. PNSO provides 2 operation codes: OC0 - BRIDGE_INFO OC3 - ADDR_INFO (new) Extend the function calls to *pnso* to pass the OC and add new response code 0108. Support for OC3 is indicated by a flag in the css_general_characteristics. Signed-off-by: Alexandra Winter <wintera@linux.ibm.com> Reviewed-by: Julian Wiedmann <jwi@linux.ibm.com> Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com> Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
afb83012cc
commit
4fea49a79e
@ -238,7 +238,6 @@ extern void ccw_device_get_schid(struct ccw_device *, struct subchannel_id *);
|
|||||||
struct channel_path_desc_fmt0 *ccw_device_get_chp_desc(struct ccw_device *, int);
|
struct channel_path_desc_fmt0 *ccw_device_get_chp_desc(struct ccw_device *, int);
|
||||||
u8 *ccw_device_get_util_str(struct ccw_device *cdev, int chp_idx);
|
u8 *ccw_device_get_util_str(struct ccw_device *cdev, int chp_idx);
|
||||||
int ccw_device_pnso(struct ccw_device *cdev,
|
int ccw_device_pnso(struct ccw_device *cdev,
|
||||||
struct chsc_pnso_area *pnso_area,
|
struct chsc_pnso_area *pnso_area, u8 oc,
|
||||||
struct chsc_pnso_resume_token resume_token,
|
struct chsc_pnso_resume_token resume_token, int cnc);
|
||||||
int cnc);
|
|
||||||
#endif /* _S390_CCWDEV_H_ */
|
#endif /* _S390_CCWDEV_H_ */
|
||||||
|
@ -11,6 +11,13 @@
|
|||||||
|
|
||||||
#include <uapi/asm/chsc.h>
|
#include <uapi/asm/chsc.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operation codes for CHSC PNSO:
|
||||||
|
* PNSO_OC_NET_BRIDGE_INFO - only addresses that are visible to a bridgeport
|
||||||
|
* PNSO_OC_NET_ADDR_INFO - all addresses
|
||||||
|
*/
|
||||||
|
#define PNSO_OC_NET_BRIDGE_INFO 0
|
||||||
|
#define PNSO_OC_NET_ADDR_INFO 3
|
||||||
/**
|
/**
|
||||||
* struct chsc_pnso_naid_l2 - network address information descriptor
|
* struct chsc_pnso_naid_l2 - network address information descriptor
|
||||||
* @nit: Network interface token
|
* @nit: Network interface token
|
||||||
|
@ -36,7 +36,9 @@ struct css_general_char {
|
|||||||
u64 alt_ssi : 1; /* bit 108 */
|
u64 alt_ssi : 1; /* bit 108 */
|
||||||
u64 : 1;
|
u64 : 1;
|
||||||
u64 narf : 1; /* bit 110 */
|
u64 narf : 1; /* bit 110 */
|
||||||
u64 : 12;
|
u64 : 5;
|
||||||
|
u64 enarf: 1; /* bit 116 */
|
||||||
|
u64 : 6;
|
||||||
u64 util_str : 1;/* bit 123 */
|
u64 util_str : 1;/* bit 123 */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
@ -65,6 +65,8 @@ int chsc_error_from_response(int response)
|
|||||||
case 0x0100:
|
case 0x0100:
|
||||||
case 0x0102:
|
case 0x0102:
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
case 0x0108: /* "HW limit exceeded" for the op 0x003d */
|
||||||
|
return -EUSERS;
|
||||||
default:
|
default:
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -1340,6 +1342,7 @@ EXPORT_SYMBOL_GPL(chsc_scm_info);
|
|||||||
* chsc_pnso() - Perform Network-Subchannel Operation
|
* chsc_pnso() - Perform Network-Subchannel Operation
|
||||||
* @schid: id of the subchannel on which PNSO is performed
|
* @schid: id of the subchannel on which PNSO is performed
|
||||||
* @pnso_area: request and response block for the operation
|
* @pnso_area: request and response block for the operation
|
||||||
|
* @oc: Operation Code
|
||||||
* @resume_token: resume token for multiblock response
|
* @resume_token: resume token for multiblock response
|
||||||
* @cnc: Boolean change-notification control
|
* @cnc: Boolean change-notification control
|
||||||
*
|
*
|
||||||
@ -1347,10 +1350,8 @@ EXPORT_SYMBOL_GPL(chsc_scm_info);
|
|||||||
*
|
*
|
||||||
* Returns 0 on success.
|
* Returns 0 on success.
|
||||||
*/
|
*/
|
||||||
int chsc_pnso(struct subchannel_id schid,
|
int chsc_pnso(struct subchannel_id schid, struct chsc_pnso_area *pnso_area,
|
||||||
struct chsc_pnso_area *pnso_area,
|
u8 oc, struct chsc_pnso_resume_token resume_token, int cnc)
|
||||||
struct chsc_pnso_resume_token resume_token,
|
|
||||||
int cnc)
|
|
||||||
{
|
{
|
||||||
memset(pnso_area, 0, sizeof(*pnso_area));
|
memset(pnso_area, 0, sizeof(*pnso_area));
|
||||||
pnso_area->request.length = 0x0030;
|
pnso_area->request.length = 0x0030;
|
||||||
@ -1359,7 +1360,7 @@ int chsc_pnso(struct subchannel_id schid,
|
|||||||
pnso_area->ssid = schid.ssid;
|
pnso_area->ssid = schid.ssid;
|
||||||
pnso_area->sch = schid.sch_no;
|
pnso_area->sch = schid.sch_no;
|
||||||
pnso_area->cssid = schid.cssid;
|
pnso_area->cssid = schid.cssid;
|
||||||
pnso_area->oc = 0; /* Store-network-bridging-information list */
|
pnso_area->oc = oc;
|
||||||
pnso_area->resume_token = resume_token;
|
pnso_area->resume_token = resume_token;
|
||||||
pnso_area->n = (cnc != 0);
|
pnso_area->n = (cnc != 0);
|
||||||
if (chsc(pnso_area))
|
if (chsc(pnso_area))
|
||||||
|
@ -205,10 +205,8 @@ struct chsc_scm_info {
|
|||||||
|
|
||||||
int chsc_scm_info(struct chsc_scm_info *scm_area, u64 token);
|
int chsc_scm_info(struct chsc_scm_info *scm_area, u64 token);
|
||||||
|
|
||||||
int chsc_pnso(struct subchannel_id schid,
|
int chsc_pnso(struct subchannel_id schid, struct chsc_pnso_area *pnso_area,
|
||||||
struct chsc_pnso_area *pnso_area,
|
u8 oc, struct chsc_pnso_resume_token resume_token, int cnc);
|
||||||
struct chsc_pnso_resume_token resume_token,
|
|
||||||
int cnc);
|
|
||||||
|
|
||||||
int __init chsc_get_cssid(int idx);
|
int __init chsc_get_cssid(int idx);
|
||||||
|
|
||||||
|
@ -714,6 +714,7 @@ EXPORT_SYMBOL_GPL(ccw_device_get_schid);
|
|||||||
* ccw_device_pnso() - Perform Network-Subchannel Operation
|
* ccw_device_pnso() - Perform Network-Subchannel Operation
|
||||||
* @cdev: device on which PNSO is performed
|
* @cdev: device on which PNSO is performed
|
||||||
* @pnso_area: request and response block for the operation
|
* @pnso_area: request and response block for the operation
|
||||||
|
* @oc: Operation Code
|
||||||
* @resume_token: resume token for multiblock response
|
* @resume_token: resume token for multiblock response
|
||||||
* @cnc: Boolean change-notification control
|
* @cnc: Boolean change-notification control
|
||||||
*
|
*
|
||||||
@ -722,14 +723,13 @@ EXPORT_SYMBOL_GPL(ccw_device_get_schid);
|
|||||||
* Returns 0 on success.
|
* Returns 0 on success.
|
||||||
*/
|
*/
|
||||||
int ccw_device_pnso(struct ccw_device *cdev,
|
int ccw_device_pnso(struct ccw_device *cdev,
|
||||||
struct chsc_pnso_area *pnso_area,
|
struct chsc_pnso_area *pnso_area, u8 oc,
|
||||||
struct chsc_pnso_resume_token resume_token,
|
struct chsc_pnso_resume_token resume_token, int cnc)
|
||||||
int cnc)
|
|
||||||
{
|
{
|
||||||
struct subchannel_id schid;
|
struct subchannel_id schid;
|
||||||
|
|
||||||
ccw_device_get_schid(cdev, &schid);
|
ccw_device_get_schid(cdev, &schid);
|
||||||
return chsc_pnso(schid, pnso_area, resume_token, cnc);
|
return chsc_pnso(schid, pnso_area, oc, resume_token, cnc);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ccw_device_pnso);
|
EXPORT_SYMBOL_GPL(ccw_device_pnso);
|
||||||
|
|
||||||
|
@ -642,6 +642,7 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
|
|||||||
/**
|
/**
|
||||||
* qeth_l2_pnso() - perform network subchannel operation
|
* qeth_l2_pnso() - perform network subchannel operation
|
||||||
* @card: qeth_card structure pointer
|
* @card: qeth_card structure pointer
|
||||||
|
* @oc: Operation Code
|
||||||
* @cnc: Boolean Change-Notification Control
|
* @cnc: Boolean Change-Notification Control
|
||||||
* @cb: Callback function will be executed for each element
|
* @cb: Callback function will be executed for each element
|
||||||
* of the address list
|
* of the address list
|
||||||
@ -652,7 +653,7 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
|
|||||||
* control" is set, further changes in the address list will be reported
|
* control" is set, further changes in the address list will be reported
|
||||||
* via the IPA command.
|
* via the IPA command.
|
||||||
*/
|
*/
|
||||||
static int qeth_l2_pnso(struct qeth_card *card, int cnc,
|
static int qeth_l2_pnso(struct qeth_card *card, u8 oc, int cnc,
|
||||||
void (*cb)(void *priv, struct chsc_pnso_naid_l2 *entry),
|
void (*cb)(void *priv, struct chsc_pnso_naid_l2 *entry),
|
||||||
void *priv)
|
void *priv)
|
||||||
{
|
{
|
||||||
@ -663,13 +664,14 @@ static int qeth_l2_pnso(struct qeth_card *card, int cnc,
|
|||||||
int i, size, elems;
|
int i, size, elems;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
QETH_CARD_TEXT(card, 2, "PNSO");
|
|
||||||
rr = (struct chsc_pnso_area *)get_zeroed_page(GFP_KERNEL);
|
rr = (struct chsc_pnso_area *)get_zeroed_page(GFP_KERNEL);
|
||||||
if (rr == NULL)
|
if (rr == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
do {
|
do {
|
||||||
|
QETH_CARD_TEXT(card, 2, "PNSO");
|
||||||
/* on the first iteration, naihdr.resume_token will be zero */
|
/* on the first iteration, naihdr.resume_token will be zero */
|
||||||
rc = ccw_device_pnso(ddev, rr, rr->naihdr.resume_token, cnc);
|
rc = ccw_device_pnso(ddev, rr, oc, rr->naihdr.resume_token,
|
||||||
|
cnc);
|
||||||
if (rc)
|
if (rc)
|
||||||
continue;
|
continue;
|
||||||
if (cb == NULL)
|
if (cb == NULL)
|
||||||
@ -1578,11 +1580,12 @@ int qeth_bridgeport_an_set(struct qeth_card *card, int enable)
|
|||||||
if (enable) {
|
if (enable) {
|
||||||
qeth_bridge_emit_host_event(card, anev_reset, 0, NULL, NULL);
|
qeth_bridge_emit_host_event(card, anev_reset, 0, NULL, NULL);
|
||||||
qeth_l2_set_pnso_mode(card, QETH_PNSO_BRIDGEPORT);
|
qeth_l2_set_pnso_mode(card, QETH_PNSO_BRIDGEPORT);
|
||||||
rc = qeth_l2_pnso(card, 1, qeth_bridgeport_an_set_cb, card);
|
rc = qeth_l2_pnso(card, PNSO_OC_NET_BRIDGE_INFO, 1,
|
||||||
|
qeth_bridgeport_an_set_cb, card);
|
||||||
if (rc)
|
if (rc)
|
||||||
qeth_l2_set_pnso_mode(card, QETH_PNSO_NONE);
|
qeth_l2_set_pnso_mode(card, QETH_PNSO_NONE);
|
||||||
} else {
|
} else {
|
||||||
rc = qeth_l2_pnso(card, 0, NULL, NULL);
|
rc = qeth_l2_pnso(card, PNSO_OC_NET_BRIDGE_INFO, 0, NULL, NULL);
|
||||||
qeth_l2_set_pnso_mode(card, QETH_PNSO_NONE);
|
qeth_l2_set_pnso_mode(card, QETH_PNSO_NONE);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user