1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * llc_pdu.c - access to PDU internals 4 * 5 * Copyright (c) 1997 by Procom Technology, Inc. 6 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> 7 */ 8 9 #include <linux/netdevice.h> 10 #include <net/llc_pdu.h> 11 12 static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type); 13 static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu); 14 15 void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type) 16 { 17 llc_pdu_un_hdr(skb)->ssap |= pdu_type; 18 } 19 20 /** 21 * llc_pdu_set_pf_bit - sets poll/final bit in LLC header 22 * @skb: Frame to set bit in 23 * @bit_value: poll/final bit (0 or 1). 24 * 25 * This function sets poll/final bit in LLC header (based on type of PDU). 26 * in I or S pdus, p/f bit is right bit of fourth byte in header. in U 27 * pdus p/f bit is fifth bit of third byte. 28 */ 29 void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value) 30 { 31 u8 pdu_type; 32 struct llc_pdu_sn *pdu; 33 34 llc_pdu_decode_pdu_type(skb, &pdu_type); 35 pdu = llc_pdu_sn_hdr(skb); 36 37 switch (pdu_type) { 38 case LLC_PDU_TYPE_I: 39 case LLC_PDU_TYPE_S: 40 pdu->ctrl_2 = (pdu->ctrl_2 & 0xFE) | bit_value; 41 break; 42 case LLC_PDU_TYPE_U: 43 pdu->ctrl_1 |= (pdu->ctrl_1 & 0xEF) | (bit_value << 4); 44 break; 45 } 46 } 47 48 /** 49 * llc_pdu_decode_pf_bit - extracs poll/final bit from LLC header 50 * @skb: input skb that p/f bit must be extracted from it 51 * @pf_bit: poll/final bit (0 or 1) 52 * 53 * This function extracts poll/final bit from LLC header (based on type of 54 * PDU). In I or S pdus, p/f bit is right bit of fourth byte in header. In 55 * U pdus p/f bit is fifth bit of third byte. 56 */ 57 void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit) 58 { 59 u8 pdu_type; 60 struct llc_pdu_sn *pdu; 61 62 llc_pdu_decode_pdu_type(skb, &pdu_type); 63 pdu = llc_pdu_sn_hdr(skb); 64 65 switch (pdu_type) { 66 case LLC_PDU_TYPE_I: 67 case LLC_PDU_TYPE_S: 68 *pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK; 69 break; 70 case LLC_PDU_TYPE_U: 71 *pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4; 72 break; 73 } 74 } 75 76 /** 77 * llc_pdu_init_as_disc_cmd - Builds DISC PDU 78 * @skb: Address of the skb to build 79 * @p_bit: The P bit to set in the PDU 80 * 81 * Builds a pdu frame as a DISC command. 82 */ 83 void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit) 84 { 85 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); 86 87 pdu->ctrl_1 = LLC_PDU_TYPE_U; 88 pdu->ctrl_1 |= LLC_2_PDU_CMD_DISC; 89 pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK; 90 } 91 92 /** 93 * llc_pdu_init_as_i_cmd - builds I pdu 94 * @skb: Address of the skb to build 95 * @p_bit: The P bit to set in the PDU 96 * @ns: The sequence number of the data PDU 97 * @nr: The seq. number of the expected I PDU from the remote 98 * 99 * Builds a pdu frame as an I command. 100 */ 101 void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr) 102 { 103 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 104 105 pdu->ctrl_1 = LLC_PDU_TYPE_I; 106 pdu->ctrl_2 = 0; 107 pdu->ctrl_2 |= (p_bit & LLC_I_PF_BIT_MASK); /* p/f bit */ 108 pdu->ctrl_1 |= (ns << 1) & 0xFE; /* set N(S) in bits 2..8 */ 109 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ 110 } 111 112 /** 113 * llc_pdu_init_as_rej_cmd - builds REJ PDU 114 * @skb: Address of the skb to build 115 * @p_bit: The P bit to set in the PDU 116 * @nr: The seq. number of the expected I PDU from the remote 117 * 118 * Builds a pdu frame as a REJ command. 119 */ 120 void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) 121 { 122 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 123 124 pdu->ctrl_1 = LLC_PDU_TYPE_S; 125 pdu->ctrl_1 |= LLC_2_PDU_CMD_REJ; 126 pdu->ctrl_2 = 0; 127 pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK; 128 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ 129 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ 130 } 131 132 /** 133 * llc_pdu_init_as_rnr_cmd - builds RNR pdu 134 * @skb: Address of the skb to build 135 * @p_bit: The P bit to set in the PDU 136 * @nr: The seq. number of the expected I PDU from the remote 137 * 138 * Builds a pdu frame as an RNR command. 139 */ 140 void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) 141 { 142 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 143 144 pdu->ctrl_1 = LLC_PDU_TYPE_S; 145 pdu->ctrl_1 |= LLC_2_PDU_CMD_RNR; 146 pdu->ctrl_2 = 0; 147 pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK; 148 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ 149 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ 150 } 151 152 /** 153 * llc_pdu_init_as_rr_cmd - Builds RR pdu 154 * @skb: Address of the skb to build 155 * @p_bit: The P bit to set in the PDU 156 * @nr: The seq. number of the expected I PDU from the remote 157 * 158 * Builds a pdu frame as an RR command. 159 */ 160 void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) 161 { 162 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 163 164 pdu->ctrl_1 = LLC_PDU_TYPE_S; 165 pdu->ctrl_1 |= LLC_2_PDU_CMD_RR; 166 pdu->ctrl_2 = p_bit & LLC_S_PF_BIT_MASK; 167 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ 168 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ 169 } 170 171 /** 172 * llc_pdu_init_as_sabme_cmd - builds SABME pdu 173 * @skb: Address of the skb to build 174 * @p_bit: The P bit to set in the PDU 175 * 176 * Builds a pdu frame as an SABME command. 177 */ 178 void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit) 179 { 180 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); 181 182 pdu->ctrl_1 = LLC_PDU_TYPE_U; 183 pdu->ctrl_1 |= LLC_2_PDU_CMD_SABME; 184 pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK; 185 } 186 187 /** 188 * llc_pdu_init_as_dm_rsp - builds DM response pdu 189 * @skb: Address of the skb to build 190 * @f_bit: The F bit to set in the PDU 191 * 192 * Builds a pdu frame as a DM response. 193 */ 194 void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit) 195 { 196 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); 197 198 pdu->ctrl_1 = LLC_PDU_TYPE_U; 199 pdu->ctrl_1 |= LLC_2_PDU_RSP_DM; 200 pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK; 201 } 202 203 /** 204 * llc_pdu_init_as_frmr_rsp - builds FRMR response PDU 205 * @skb: Address of the frame to build 206 * @prev_pdu: The rejected PDU frame 207 * @f_bit: The F bit to set in the PDU 208 * @vs: tx state vari value for the data link conn at the rejecting LLC 209 * @vr: rx state var value for the data link conn at the rejecting LLC 210 * @vzyxw: completely described in the IEEE Std 802.2 document (Pg 55) 211 * 212 * Builds a pdu frame as a FRMR response. 213 */ 214 void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu, 215 u8 f_bit, u8 vs, u8 vr, u8 vzyxw) 216 { 217 struct llc_frmr_info *frmr_info; 218 u8 prev_pf = 0; 219 u8 *ctrl; 220 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 221 222 pdu->ctrl_1 = LLC_PDU_TYPE_U; 223 pdu->ctrl_1 |= LLC_2_PDU_RSP_FRMR; 224 pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK; 225 226 frmr_info = (struct llc_frmr_info *)&pdu->ctrl_2; 227 ctrl = (u8 *)&prev_pdu->ctrl_1; 228 FRMR_INFO_SET_REJ_CNTRL(frmr_info,ctrl); 229 FRMR_INFO_SET_Vs(frmr_info, vs); 230 FRMR_INFO_SET_Vr(frmr_info, vr); 231 prev_pf = llc_pdu_get_pf_bit(prev_pdu); 232 FRMR_INFO_SET_C_R_BIT(frmr_info, prev_pf); 233 FRMR_INFO_SET_INVALID_PDU_CTRL_IND(frmr_info, vzyxw); 234 FRMR_INFO_SET_INVALID_PDU_INFO_IND(frmr_info, vzyxw); 235 FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw); 236 FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw); 237 FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw); 238 skb_put(skb, sizeof(struct llc_frmr_info)); 239 } 240 241 /** 242 * llc_pdu_init_as_rr_rsp - builds RR response pdu 243 * @skb: Address of the skb to build 244 * @f_bit: The F bit to set in the PDU 245 * @nr: The seq. number of the expected data PDU from the remote 246 * 247 * Builds a pdu frame as an RR response. 248 */ 249 void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) 250 { 251 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 252 253 pdu->ctrl_1 = LLC_PDU_TYPE_S; 254 pdu->ctrl_1 |= LLC_2_PDU_RSP_RR; 255 pdu->ctrl_2 = 0; 256 pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK; 257 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ 258 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ 259 } 260 261 /** 262 * llc_pdu_init_as_rej_rsp - builds REJ response pdu 263 * @skb: Address of the skb to build 264 * @f_bit: The F bit to set in the PDU 265 * @nr: The seq. number of the expected data PDU from the remote 266 * 267 * Builds a pdu frame as a REJ response. 268 */ 269 void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) 270 { 271 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 272 273 pdu->ctrl_1 = LLC_PDU_TYPE_S; 274 pdu->ctrl_1 |= LLC_2_PDU_RSP_REJ; 275 pdu->ctrl_2 = 0; 276 pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK; 277 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ 278 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ 279 } 280 281 /** 282 * llc_pdu_init_as_rnr_rsp - builds RNR response pdu 283 * @skb: Address of the frame to build 284 * @f_bit: The F bit to set in the PDU 285 * @nr: The seq. number of the expected data PDU from the remote 286 * 287 * Builds a pdu frame as an RNR response. 288 */ 289 void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) 290 { 291 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 292 293 pdu->ctrl_1 = LLC_PDU_TYPE_S; 294 pdu->ctrl_1 |= LLC_2_PDU_RSP_RNR; 295 pdu->ctrl_2 = 0; 296 pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK; 297 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ 298 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ 299 } 300 301 /** 302 * llc_pdu_init_as_ua_rsp - builds UA response pdu 303 * @skb: Address of the frame to build 304 * @f_bit: The F bit to set in the PDU 305 * 306 * Builds a pdu frame as a UA response. 307 */ 308 void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit) 309 { 310 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); 311 312 pdu->ctrl_1 = LLC_PDU_TYPE_U; 313 pdu->ctrl_1 |= LLC_2_PDU_RSP_UA; 314 pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK; 315 } 316 317 /** 318 * llc_pdu_decode_pdu_type - designates PDU type 319 * @skb: input skb that type of it must be designated. 320 * @type: type of PDU (output argument). 321 * 322 * This function designates type of PDU (I, S or U). 323 */ 324 static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type) 325 { 326 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); 327 328 if (pdu->ctrl_1 & 1) { 329 if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U) 330 *type = LLC_PDU_TYPE_U; 331 else 332 *type = LLC_PDU_TYPE_S; 333 } else 334 *type = LLC_PDU_TYPE_I; 335 } 336 337 /** 338 * llc_pdu_get_pf_bit - extracts p/f bit of input PDU 339 * @pdu: pointer to LLC header. 340 * 341 * This function extracts p/f bit of input PDU. at first examines type of 342 * PDU and then extracts p/f bit. Returns the p/f bit. 343 */ 344 static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu) 345 { 346 u8 pdu_type; 347 u8 pf_bit = 0; 348 349 if (pdu->ctrl_1 & 1) { 350 if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U) 351 pdu_type = LLC_PDU_TYPE_U; 352 else 353 pdu_type = LLC_PDU_TYPE_S; 354 } else 355 pdu_type = LLC_PDU_TYPE_I; 356 switch (pdu_type) { 357 case LLC_PDU_TYPE_I: 358 case LLC_PDU_TYPE_S: 359 pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK; 360 break; 361 case LLC_PDU_TYPE_U: 362 pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4; 363 break; 364 } 365 return pf_bit; 366 } 367