From: Hendrik Brueckner <brueckner@redhat.com> Date: Mon, 19 Jul 2010 11:47:55 -0400 Subject: [s390] qeth: support for OSA CHPID types OSX and OSM Message-id: <1279540075-25959-2-git-send-email-brueckner@redhat.com> Patchwork-id: 26944 O-Subject: [RHEL5.6 PATCH 2/2] [s390x] qeth: support for OSA CHPID types OSX and OSM Bugzilla: 599644 RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com> Description ----------- This patch adds support for new OSA CHPID types OSX and OSM. Bugzilla -------- BZ 599644 https://bugzilla.redhat.com/show_bug.cgi?id=599644 Upstream status of the patch ---------------------------- The patch is upstream as of kernel version 2.6.35 http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=5113fec0984276836cb6f0677f7cb53586ec3451 Test status ----------- The patch has been tested and fixes the problem. The fix has been verified by the IBM test department. diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 629e021..1fb19f6 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -270,6 +270,8 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) #define QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT 0x0101 #define QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT 0x4108 #define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108 +#define QETH_IDX_FUNC_LEVEL_OSM 0x4131 +#define QETH_IDX_FUNC_LEVEL_OSX 0x4130 #define QETH_MODELLIST_ARRAY \ {{0x1731,0x01,0x1732,0x01,QETH_CARD_TYPE_OSAE,1, \ @@ -284,6 +286,14 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \ QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \ QETH_MAX_QUEUES,0}, \ + {0x1731,0x02,0x1732,0x03,QETH_CARD_TYPE_OSM,1, \ + QETH_IDX_FUNC_LEVEL_OSM, \ + QETH_IDX_FUNC_LEVEL_OSM, \ + QETH_MAX_QUEUES,0}, \ + {0x1731,0x02,0x1732,0x02,QETH_CARD_TYPE_OSX,1, \ + QETH_IDX_FUNC_LEVEL_OSX, \ + QETH_IDX_FUNC_LEVEL_OSX, \ + QETH_MAX_QUEUES,0}, \ {0,0,0,0,0,0,0,0,0}} #define QETH_REAL_CARD 1 @@ -982,6 +992,9 @@ qeth_get_initial_mtu_for_card(struct qeth_card * card) default: return 1492; } + case QETH_CARD_TYPE_OSM: + case QETH_CARD_TYPE_OSX: + return 1492; default: return 1500; } @@ -995,6 +1008,8 @@ qeth_get_max_mtu_for_card(int cardtype) case QETH_CARD_TYPE_UNKNOWN: case QETH_CARD_TYPE_OSAE: case QETH_CARD_TYPE_OSN: + case QETH_CARD_TYPE_OSM: + case QETH_CARD_TYPE_OSX: return 61440; case QETH_CARD_TYPE_IQD: return 57344; @@ -1036,6 +1051,8 @@ qeth_mtu_is_valid(struct qeth_card * card, int mtu) { switch (card->info.type) { case QETH_CARD_TYPE_OSAE: + case QETH_CARD_TYPE_OSM: + case QETH_CARD_TYPE_OSX: return ((mtu >= 576) && (mtu <= 61440)); case QETH_CARD_TYPE_IQD: return ((mtu >= 576) && diff --git a/drivers/s390/net/qeth_fs.h b/drivers/s390/net/qeth_fs.h index 61faf05..b902996 100644 --- a/drivers/s390/net/qeth_fs.h +++ b/drivers/s390/net/qeth_fs.h @@ -100,6 +100,10 @@ qeth_get_cardname(struct qeth_card *card) return " Guest LAN QDIO"; case QETH_CARD_TYPE_IQD: return " Guest LAN Hiper"; + case QETH_CARD_TYPE_OSM: + return " Guest LAN QDIO - OSM"; + case QETH_CARD_TYPE_OSX: + return " Guest LAN QDIO - OSX"; default: return " unknown"; } @@ -111,6 +115,10 @@ qeth_get_cardname(struct qeth_card *card) return " HiperSockets"; case QETH_CARD_TYPE_OSN: return " OSN QDIO"; + case QETH_CARD_TYPE_OSM: + return " OSM QDIO"; + case QETH_CARD_TYPE_OSX: + return " OSX QDIO"; default: return " unknown"; } @@ -128,6 +136,10 @@ qeth_get_cardname_short(struct qeth_card *card) return "GuestLAN QDIO"; case QETH_CARD_TYPE_IQD: return "GuestLAN Hiper"; + case QETH_CARD_TYPE_OSM: + return "GuestLAN OSM"; + case QETH_CARD_TYPE_OSX: + return "GuestLAN OSX"; default: return "unknown"; } @@ -158,6 +170,10 @@ qeth_get_cardname_short(struct qeth_card *card) return "HiperSockets"; case QETH_CARD_TYPE_OSN: return "OSN"; + case QETH_CARD_TYPE_OSM: + return "OSM_1000"; + case QETH_CARD_TYPE_OSX: + return "OSX_10GIG"; default: return "unknown"; } diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index e345818..8513ef8 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -365,7 +365,7 @@ qeth_get_problem(struct ccw_device *cdev, struct irb *irb) SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK | SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) { QETH_DBF_TEXT(trace,2, "CGENCHK"); - PRINT_WARN("check on device %s, dstat=x%x, cstat=x%x ", + PRINT_WARN("check on device %s, dstat=x%x, cstat=x%x \n", cdev->dev.bus_id, dstat, cstat); HEXDUMP16(WARN, "irb: ", irb); HEXDUMP16(WARN, "irb: ", ((char *) irb) + 32); @@ -1050,7 +1050,8 @@ qeth_set_intial_options(struct qeth_card *card) card->options.fake_broadcast = 0; card->options.add_hhlen = DEFAULT_ADD_HHLEN; card->options.fake_ll = 0; - if (card->info.type == QETH_CARD_TYPE_OSN) + if (card->info.type == QETH_CARD_TYPE_OSN || + card->info.type == QETH_CARD_TYPE_OSM) card->options.layer2 = 1; else card->options.layer2 = 0; @@ -1131,6 +1132,7 @@ is_1920_device (struct qeth_card *card) if (chp_dsc != NULL) { /* CHPP field bit 6 == 1 -> single queue */ single_queue = ((chp_dsc->chpp & 0x02) == 0x02); + card->info.func_level = 0x4100 + chp_dsc->desc; kfree(chp_dsc); } QETH_DBF_TEXT_(setup, 2, "rc:%x", single_queue); @@ -1150,6 +1152,7 @@ qeth_determine_card_type(struct qeth_card *card) if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) && (CARD_RDEV(card)->id.dev_model == known_devices[i][3])) { card->info.type = known_devices[i][4]; + card->info.func_level = known_devices[i][7]; card->qdio.no_out_queues = known_devices[i][8]; card->info.is_multicast_different = known_devices[i][9]; if (is_1920_device(card)) { @@ -1597,9 +1600,16 @@ qeth_idx_read_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob) PRINT_ERR("IDX_ACTIVATE on read channel device %s: " "adapter exclusively used by another host\n", CARD_RDEV_ID(card)); + else if ((QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x1e) || + (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x20)) + PRINT_ERR("IDX ACTIVATE on read channel device %s: " + "insufficient authorization\n", + CARD_RDEV_ID(card)); else PRINT_ERR("IDX_ACTIVATE on read channel device %s: " "negative reply\n", CARD_RDEV_ID(card)); + QETH_DBF_TEXT_(setup, 2, "idxread%c", + QETH_IDX_ACT_CAUSE_CODE(iob->data)); goto out; } @@ -3782,6 +3792,8 @@ qeth_get_netdevice(enum qeth_card_types type, enum qeth_link_types linktype) switch (type) { case QETH_CARD_TYPE_OSAE: + case QETH_CARD_TYPE_OSM: + case QETH_CARD_TYPE_OSX: switch (linktype) { case QETH_LINK_TYPE_LANE_TR: case QETH_LINK_TYPE_HSTR: @@ -4046,7 +4058,8 @@ static inline int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, int ipv, int cast_type) { - if (!ipv && (card->info.type == QETH_CARD_TYPE_OSAE)) + if (!ipv && (card->info.type == QETH_CARD_TYPE_OSAE || + card->info.type == QETH_CARD_TYPE_OSX)) return card->qdio.default_out_queue; switch (card->qdio.no_out_queues) { case 4: @@ -5377,7 +5390,9 @@ qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data); break; case SIOC_QETH_GET_CARD_TYPE: - if ((card->info.type == QETH_CARD_TYPE_OSAE) && + if ((card->info.type == QETH_CARD_TYPE_OSAE || + card->info.type == QETH_CARD_TYPE_OSM || + card->info.type == QETH_CARD_TYPE_OSX) && !card->info.guestlan) return 1; return 0; @@ -5595,6 +5610,9 @@ qeth_layer2_process_vlans(struct qeth_card *card, int clear) QETH_DBF_TEXT(trace, 3, "L2prcvln"); + if (card->info.type == QETH_CARD_TYPE_OSN || + card->info.type == QETH_CARD_TYPE_OSM) + return; if (!card->vlangrp) return; for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { @@ -5618,6 +5636,10 @@ qeth_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) card = (struct qeth_card *) dev->priv; if (!card->options.layer2) return; + if (card->info.type == QETH_CARD_TYPE_OSM) { + QETH_DBF_TEXT(trace, 3, "aidOSM"); + return; + } qeth_layer2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN); } @@ -5632,6 +5654,10 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) card = (struct qeth_card *) dev->priv; /* free all skbs for the vlan device */ + if (card->info.type == QETH_CARD_TYPE_OSM) { + QETH_DBF_TEXT(trace, 3, "kidOSM"); + return; + } qeth_free_vlan_skbs(card, vid); spin_lock_irqsave(&card->vlanlock, flags); /* unregister IP addresses of vlan device */ @@ -6214,7 +6240,9 @@ qeth_layer2_set_mac_address(struct net_device *dev, void *p) QETH_DBF_TEXT(trace, 3, "setmcLY3"); return -EOPNOTSUPP; } - if (card->info.type == QETH_CARD_TYPE_OSN) { + if (card->info.type == QETH_CARD_TYPE_OSN || + card->info.type == QETH_CARD_TYPE_OSM || + card->info.type == QETH_CARD_TYPE_OSX) { PRINT_WARN("Setting MAC address on %s is not supported.\n", dev->name); QETH_DBF_TEXT(trace, 3, "setmcOSN"); @@ -6610,15 +6638,17 @@ qeth_init_func_level(struct qeth_card *card) if (card->info.type == QETH_CARD_TYPE_IQD) card->info.func_level = QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT; - else + else if (card->info.type == QETH_CARD_TYPE_OSAE) card->info.func_level = QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT; + else ; } else { if (card->info.type == QETH_CARD_TYPE_IQD) /*FIXME:why do we have same values for dis and ena for osae??? */ card->info.func_level = QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT; - else + else if (card->info.type == QETH_CARD_TYPE_OSAE || + card->info.type == QETH_CARD_TYPE_OSN) card->info.func_level = QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT; } @@ -8010,6 +8040,8 @@ qeth_print_status_message(struct qeth_card *card) { switch (card->info.type) { case QETH_CARD_TYPE_OSAE: + case QETH_CARD_TYPE_OSM: + case QETH_CARD_TYPE_OSX: /* VM will use a non-zero first character * to indicate a HiperSockets like reporting * of the level OSA sets the first character to zero @@ -8158,9 +8190,16 @@ qeth_set_online(struct ccwgroup_device *gdev) } static struct ccw_device_id qeth_ids[] = { - {CCW_DEVICE(0x1731, 0x01), .driver_info = QETH_CARD_TYPE_OSAE}, - {CCW_DEVICE(0x1731, 0x05), .driver_info = QETH_CARD_TYPE_IQD}, - {CCW_DEVICE(0x1731, 0x06), .driver_info = QETH_CARD_TYPE_OSN}, + {CCW_DEVICE_DEVTYPE(0x1731, 0x01, 0x1732, 0x01), + .driver_info = QETH_CARD_TYPE_OSAE}, + {CCW_DEVICE_DEVTYPE(0x1731, 0x05, 0x1732, 0x05), + .driver_info = QETH_CARD_TYPE_IQD}, + {CCW_DEVICE_DEVTYPE(0x1731, 0x06, 0x1732, 0x06), + .driver_info = QETH_CARD_TYPE_OSN}, + {CCW_DEVICE_DEVTYPE(0x1731, 0x02, 0x1732, 0x03), + .driver_info = QETH_CARD_TYPE_OSM}, + {CCW_DEVICE_DEVTYPE(0x1731, 0x02, 0x1732, 0x02), + .driver_info = QETH_CARD_TYPE_OSX}, {}, }; MODULE_DEVICE_TABLE(ccw, qeth_ids); diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h index 7a7690b..637bb38 100644 --- a/drivers/s390/net/qeth_mpc.h +++ b/drivers/s390/net/qeth_mpc.h @@ -52,6 +52,8 @@ enum qeth_card_types { QETH_CARD_TYPE_OSAE = 10, QETH_CARD_TYPE_IQD = 1234, QETH_CARD_TYPE_OSN = 11, + QETH_CARD_TYPE_OSM = 3, + QETH_CARD_TYPE_OSX = 2, }; #define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18 diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c index 1579977..b149223 100644 --- a/drivers/s390/net/qeth_sys.c +++ b/drivers/s390/net/qeth_sys.c @@ -711,6 +711,10 @@ qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const c if (!card) return -EINVAL; + if (card->info.type == QETH_CARD_TYPE_OSN || + card->info.type == QETH_CARD_TYPE_OSM) + return -EPERM; + if (card->state != CARD_STATE_DOWN) return -EPERM;