0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/netdevice.h>
0016 #include <net/llc_pdu.h>
0017
0018 static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type);
0019 static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu);
0020
0021 void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type)
0022 {
0023 llc_pdu_un_hdr(skb)->ssap |= pdu_type;
0024 }
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value)
0036 {
0037 u8 pdu_type;
0038 struct llc_pdu_sn *pdu;
0039
0040 llc_pdu_decode_pdu_type(skb, &pdu_type);
0041 pdu = llc_pdu_sn_hdr(skb);
0042
0043 switch (pdu_type) {
0044 case LLC_PDU_TYPE_I:
0045 case LLC_PDU_TYPE_S:
0046 pdu->ctrl_2 = (pdu->ctrl_2 & 0xFE) | bit_value;
0047 break;
0048 case LLC_PDU_TYPE_U:
0049 pdu->ctrl_1 |= (pdu->ctrl_1 & 0xEF) | (bit_value << 4);
0050 break;
0051 }
0052 }
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit)
0064 {
0065 u8 pdu_type;
0066 struct llc_pdu_sn *pdu;
0067
0068 llc_pdu_decode_pdu_type(skb, &pdu_type);
0069 pdu = llc_pdu_sn_hdr(skb);
0070
0071 switch (pdu_type) {
0072 case LLC_PDU_TYPE_I:
0073 case LLC_PDU_TYPE_S:
0074 *pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK;
0075 break;
0076 case LLC_PDU_TYPE_U:
0077 *pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4;
0078 break;
0079 }
0080 }
0081
0082
0083
0084
0085
0086
0087
0088
0089 void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit)
0090 {
0091 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0092
0093 pdu->ctrl_1 = LLC_PDU_TYPE_U;
0094 pdu->ctrl_1 |= LLC_2_PDU_CMD_DISC;
0095 pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr)
0108 {
0109 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0110
0111 pdu->ctrl_1 = LLC_PDU_TYPE_I;
0112 pdu->ctrl_2 = 0;
0113 pdu->ctrl_2 |= (p_bit & LLC_I_PF_BIT_MASK);
0114 pdu->ctrl_1 |= (ns << 1) & 0xFE;
0115 pdu->ctrl_2 |= (nr << 1) & 0xFE;
0116 }
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
0127 {
0128 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0129
0130 pdu->ctrl_1 = LLC_PDU_TYPE_S;
0131 pdu->ctrl_1 |= LLC_2_PDU_CMD_REJ;
0132 pdu->ctrl_2 = 0;
0133 pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK;
0134 pdu->ctrl_1 &= 0x0F;
0135 pdu->ctrl_2 |= (nr << 1) & 0xFE;
0136 }
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146 void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
0147 {
0148 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0149
0150 pdu->ctrl_1 = LLC_PDU_TYPE_S;
0151 pdu->ctrl_1 |= LLC_2_PDU_CMD_RNR;
0152 pdu->ctrl_2 = 0;
0153 pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK;
0154 pdu->ctrl_1 &= 0x0F;
0155 pdu->ctrl_2 |= (nr << 1) & 0xFE;
0156 }
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
0167 {
0168 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0169
0170 pdu->ctrl_1 = LLC_PDU_TYPE_S;
0171 pdu->ctrl_1 |= LLC_2_PDU_CMD_RR;
0172 pdu->ctrl_2 = p_bit & LLC_S_PF_BIT_MASK;
0173 pdu->ctrl_1 &= 0x0F;
0174 pdu->ctrl_2 |= (nr << 1) & 0xFE;
0175 }
0176
0177
0178
0179
0180
0181
0182
0183
0184 void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit)
0185 {
0186 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0187
0188 pdu->ctrl_1 = LLC_PDU_TYPE_U;
0189 pdu->ctrl_1 |= LLC_2_PDU_CMD_SABME;
0190 pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
0191 }
0192
0193
0194
0195
0196
0197
0198
0199
0200 void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit)
0201 {
0202 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0203
0204 pdu->ctrl_1 = LLC_PDU_TYPE_U;
0205 pdu->ctrl_1 |= LLC_2_PDU_RSP_DM;
0206 pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
0221 u8 f_bit, u8 vs, u8 vr, u8 vzyxw)
0222 {
0223 struct llc_frmr_info *frmr_info;
0224 u8 prev_pf = 0;
0225 u8 *ctrl;
0226 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0227
0228 pdu->ctrl_1 = LLC_PDU_TYPE_U;
0229 pdu->ctrl_1 |= LLC_2_PDU_RSP_FRMR;
0230 pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
0231
0232 frmr_info = (struct llc_frmr_info *)&pdu->ctrl_2;
0233 ctrl = (u8 *)&prev_pdu->ctrl_1;
0234 FRMR_INFO_SET_REJ_CNTRL(frmr_info,ctrl);
0235 FRMR_INFO_SET_Vs(frmr_info, vs);
0236 FRMR_INFO_SET_Vr(frmr_info, vr);
0237 prev_pf = llc_pdu_get_pf_bit(prev_pdu);
0238 FRMR_INFO_SET_C_R_BIT(frmr_info, prev_pf);
0239 FRMR_INFO_SET_INVALID_PDU_CTRL_IND(frmr_info, vzyxw);
0240 FRMR_INFO_SET_INVALID_PDU_INFO_IND(frmr_info, vzyxw);
0241 FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw);
0242 FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw);
0243 FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw);
0244 skb_put(skb, sizeof(struct llc_frmr_info));
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255 void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
0256 {
0257 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0258
0259 pdu->ctrl_1 = LLC_PDU_TYPE_S;
0260 pdu->ctrl_1 |= LLC_2_PDU_RSP_RR;
0261 pdu->ctrl_2 = 0;
0262 pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK;
0263 pdu->ctrl_1 &= 0x0F;
0264 pdu->ctrl_2 |= (nr << 1) & 0xFE;
0265 }
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275 void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
0276 {
0277 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0278
0279 pdu->ctrl_1 = LLC_PDU_TYPE_S;
0280 pdu->ctrl_1 |= LLC_2_PDU_RSP_REJ;
0281 pdu->ctrl_2 = 0;
0282 pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK;
0283 pdu->ctrl_1 &= 0x0F;
0284 pdu->ctrl_2 |= (nr << 1) & 0xFE;
0285 }
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295 void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
0296 {
0297 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0298
0299 pdu->ctrl_1 = LLC_PDU_TYPE_S;
0300 pdu->ctrl_1 |= LLC_2_PDU_RSP_RNR;
0301 pdu->ctrl_2 = 0;
0302 pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK;
0303 pdu->ctrl_1 &= 0x0F;
0304 pdu->ctrl_2 |= (nr << 1) & 0xFE;
0305 }
0306
0307
0308
0309
0310
0311
0312
0313
0314 void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit)
0315 {
0316 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0317
0318 pdu->ctrl_1 = LLC_PDU_TYPE_U;
0319 pdu->ctrl_1 |= LLC_2_PDU_RSP_UA;
0320 pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
0321 }
0322
0323
0324
0325
0326
0327
0328
0329
0330 static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type)
0331 {
0332 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
0333
0334 if (pdu->ctrl_1 & 1) {
0335 if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U)
0336 *type = LLC_PDU_TYPE_U;
0337 else
0338 *type = LLC_PDU_TYPE_S;
0339 } else
0340 *type = LLC_PDU_TYPE_I;
0341 }
0342
0343
0344
0345
0346
0347
0348
0349
0350 static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu)
0351 {
0352 u8 pdu_type;
0353 u8 pf_bit = 0;
0354
0355 if (pdu->ctrl_1 & 1) {
0356 if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U)
0357 pdu_type = LLC_PDU_TYPE_U;
0358 else
0359 pdu_type = LLC_PDU_TYPE_S;
0360 } else
0361 pdu_type = LLC_PDU_TYPE_I;
0362 switch (pdu_type) {
0363 case LLC_PDU_TYPE_I:
0364 case LLC_PDU_TYPE_S:
0365 pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK;
0366 break;
0367 case LLC_PDU_TYPE_U:
0368 pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4;
0369 break;
0370 }
0371 return pf_bit;
0372 }